Dark Mode Favicons: How to Make Your Icon Adapt Automatically
SVG favicons can respond to prefers-color-scheme. Learn how to build favicons that look right in both light and dark browser themes.
Over 80% of smartphone users have dark mode enabled, and desktop adoption keeps climbing. When someone switches to dark mode, their browser chrome turns dark, and your favicon needs to survive that transition.
A dark-colored favicon that looked great on a white tab bar becomes invisible on a dark one. A light-colored icon that pops in dark mode looks washed out in light mode. Try it: open your browser with 15 tabs and toggle between themes. You will be surprised how many favicons just vanish.
Dark Mode Adoption by Browser
Dark mode is not a niche preference anymore. Here is the estimated percentage of users with dark mode enabled across major browsers in 2026.
Samsung Internet leads at 85% — driven by Android's system-wide dark mode that cascades to the browser. Safari is close behind at 82% because Apple pushed dark mode aggressively since macOS Mojave and iOS 13. Even Firefox, with the lowest adoption, has more than two-thirds of users in dark mode. The takeaway: designing favicons for light mode only means ignoring the majority of your audience.
The SVG Solution
SVG is the only favicon format that can adapt to dark mode on its own. The trick is CSS media queries embedded directly in the SVG file. When the browser detects prefers-color-scheme: dark, the SVG swaps its colors automatically. No JavaScript needed, and no extra files to manage.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<style>
.icon { fill: #DA7756; }
.bg { fill: transparent; }
@media (prefers-color-scheme: dark) {
.icon { fill: #F0B08A; }
.bg { fill: transparent; }
}
</style>
<rect class="bg" width="32" height="32" rx="6"/>
<path class="icon" d="M8 24 L16 6 L24 24 H8Z"/>
</svg>Lighter in dark mode, darker in light
The SVG Approach: A Complete Example
The basic example above uses a transparent background, which works when your icon color has enough contrast on both light and dark tab bars. But the safest approach is to include a background shape that also adapts to the theme. Here is a production-ready SVG favicon that handles both modes robustly.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<style>
/* Light mode: dark icon on light background */
.bg { fill: #FFFFFF; }
.icon-primary { fill: #1A1A2E; }
.icon-accent { fill: #DA7756; }
/* Dark mode: light icon on dark background */
@media (prefers-color-scheme: dark) {
.bg { fill: #1A1A2E; }
.icon-primary { fill: #FFFFFF; }
.icon-accent { fill: #F0B08A; }
}
</style>
<!-- Background — provides contrast on any browser chrome -->
<rect class="bg" width="32" height="32" rx="6" />
<!-- Primary shape -->
<path class="icon-primary" d="M7 25 L16 5 L25 25 Z" />
<!-- Accent detail — visible at 32px+, may merge at 16px -->
<circle class="icon-accent" cx="16" cy="20" r="3" />
</svg>A few things to note in this example. The background rectangle has rx="6" for rounded corners, which looks polished in browser tabs. The icon uses two CSS classes (icon-primary and icon-accent) so you can adjust multiple colors independently. The accent detail (the small circle) will only be visible at larger sizes — at 16px it merges with the primary shape, which is fine. This is progressive simplification happening naturally.
This SVG file goes in your public/ directory and is referenced in your HTML head:
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="icon" href="/favicon.ico" sizes="48x48" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />The Meta Theme-Color Approach
Beyond the favicon itself, you can control the color of the browser chrome — the address bar, the tab bar area, and the status bar on mobile. The meta name="theme-color" tag sets this color, and it supports media queries for dark mode adaptation.
<!-- Light mode: white browser chrome -->
<meta name="theme-color"
content="#FFFFFF"
media="(prefers-color-scheme: light)" />
<!-- Dark mode: dark browser chrome -->
<meta name="theme-color"
content="#1A1A2E"
media="(prefers-color-scheme: dark)" />This makes the entire browser chrome adapt to the user's theme, not just the favicon. On Android Chrome, this colors the address bar. On Safari (both macOS and iOS), it influences the tab bar tint. The combination of a theme-adaptive SVG favicon and matching theme-color meta tags creates a fully cohesive dark mode experience.
Safari and theme-color
Browser Support
| Browser | SVG favicon | Dark mode CSS in SVG |
|---|---|---|
| Chrome 80+ | ||
| Firefox 41+ | ||
| Edge 80+ | ||
| Safari 15+ (macOS) | ||
| Safari (iOS) | ||
| Samsung Internet | ||
| Opera |
Safari on iOS is the notable holdout. It does not support SVG favicons at all, relying instead on the Apple Touch Icon (a static 180x180 PNG). For iOS users, you need a separate approach if dark mode adaptation matters.
Framework-Specific Solutions
Next.js App Router
Next.js 13+ with the App Router supports dynamic metadata through the generateMetadata function. While you cannot use JavaScript media queries at build time, you can serve the SVG favicon (which handles dark mode internally) alongside platform-specific icons.
import type { Metadata } from 'next'
export const metadata: Metadata = {
icons: {
// SVG handles dark mode automatically via CSS media queries
icon: [
{ url: '/favicon.svg', type: 'image/svg+xml' },
{ url: '/favicon.ico', sizes: '48x48' },
],
// Static PNG for iOS — no dark mode adaptation
apple: '/apple-touch-icon.png',
},
// Theme color adapts the browser chrome
other: {
'theme-color-light': '#FFFFFF',
'theme-color-dark': '#1A1A2E',
},
}
// For dynamic theme-color with media queries,
// add these tags in your root layout's <head>:
// <meta name="theme-color" content="#FFFFFF"
// media="(prefers-color-scheme: light)" />
// <meta name="theme-color" content="#1A1A2E"
// media="(prefers-color-scheme: dark)" />React (with React Helmet or similar)
In a React SPA, you can dynamically swap the favicon based on the user's color scheme preference. React Helmet (or react-helmet-async) lets you declaratively manage the document head.
import { Helmet } from 'react-helmet-async'
import { useEffect, useState } from 'react'
export function FaviconManager() {
const [isDark, setIsDark] = useState(false)
useEffect(() => {
const mq = window.matchMedia('(prefers-color-scheme: dark)')
setIsDark(mq.matches)
const handler = (e: MediaQueryListEvent) => setIsDark(e.matches)
mq.addEventListener('change', handler)
return () => mq.removeEventListener('change', handler)
}, [])
return (
<Helmet>
{/* SVG favicon handles dark mode via CSS, but use as primary */}
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
{/* Fallback PNG — swap based on theme */}
<link rel="icon" href={isDark ? '/icon-dark.png' : '/icon-light.png'}
type="image/png" sizes="32x32" />
<meta name="theme-color"
content={isDark ? '#1A1A2E' : '#FFFFFF'} />
</Helmet>
)
}Plain HTML
If you are not using a framework, the simplest approach is to declare the SVG favicon in your HTML (it handles dark mode automatically) and optionally add a small inline script for PNG fallback.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- SVG with embedded dark mode CSS — the primary approach -->
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<!-- ICO fallback for browsers that don't support SVG -->
<link rel="icon" href="/favicon.ico" sizes="48x48" />
<!-- iOS -->
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<!-- Theme color with dark mode support -->
<meta name="theme-color" content="#FFFFFF"
media="(prefers-color-scheme: light)" />
<meta name="theme-color" content="#1A1A2E"
media="(prefers-color-scheme: dark)" />
<!-- Optional: JS-based PNG swap for browsers
that support PNG but not SVG favicons -->
<script>
(function() {
var mq = window.matchMedia('(prefers-color-scheme: dark)');
var link = document.querySelector('link[sizes="32x32"]');
if (link) {
function update(e) {
link.href = e.matches ? '/icon-dark-32.png' : '/icon-light-32.png';
}
update(mq);
mq.addEventListener('change', update);
}
})();
</script>
</head>Alternative Approaches
The contrast border method
If SVG support coverage is not sufficient for your audience, a simpler approach works everywhere: add a visible border or background shape to your favicon that provides contrast in both modes. A dark icon inside a light rounded square works on dark backgrounds. A light icon inside a dark rounded square works on light backgrounds. A mid-tone background works acceptably on both.
The dual-PNG method
Some developers serve different PNGs based on theme detection. This requires JavaScript to check matchMedia('(prefers-color-scheme: dark)') and swap the favicon link dynamically. It works but adds complexity and can flash the wrong icon during page load before the script runs.
// Swap favicon based on color scheme
const setFavicon = (isDark) => {
const link = document.querySelector("link[rel='icon']")
if (link) {
link.href = isDark ? '/favicon-dark.png' : '/favicon-light.png'
}
}
// Initial set
setFavicon(matchMedia('(prefers-color-scheme: dark)').matches)
// Listen for changes
matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', (e) => setFavicon(e.matches))Flash of wrong icon
Testing Dark Mode Favicons
You do not need to toggle your entire operating system between light and dark mode to test. Chrome DevTools has a built-in emulator for prefers-color-scheme that lets you switch instantly.
- Open Chrome DevTools (F12 or Cmd+Option+I).
- Press Cmd+Shift+P (or Ctrl+Shift+P on Windows) to open the command palette.
- Type "Rendering" and select "Show Rendering".
- Scroll down to "Emulate CSS media feature prefers-color-scheme".
- Toggle between
prefers-color-scheme: lightandprefers-color-scheme: dark.
Your SVG favicon will update in real time as you toggle. This is the fastest way to verify that your dark mode colors are correct without touching your OS settings.
For Firefox, go to about:config, search for ui.systemUsesDarkTheme, and set it to 1 for dark or 0 for light. In Safari, you can toggle dark mode via the Develop menu → WebKit Feature Flags, but the most reliable method is toggling macOS System Preferences → Appearance.
Test both transitions
iOS 18 Tinted Icons
Starting with iOS 18, Apple introduced automatic icon tinting on the home screen. Users can choose a tint color, and iOS applies it to all app icons — including web app shortcuts added via "Add to Home Screen." This means your carefully chosen brand colors might be overridden by the user's preferred tint.
iOS 18 tinting works by analyzing the luminance of your icon and applying the user's chosen tint color while preserving the relative light/dark areas. Icons with clear contrast and simple shapes survive tinting well — the shape remains recognizable even when the colors change. Icons that rely on specific colors for meaning (like a red notification badge or a multi-colored logo) lose information when tinted.
To prepare for tinting, focus on strong silhouettes rather than color. Make sure your apple-touch-icon has a clear shape with good contrast between the foreground and background. Test by converting your icon to grayscale — if it is still recognizable, it will survive tinting. If it becomes an indistinguishable gray blob, simplify the design.
| Design choice | Survives tinting? | Why |
|---|---|---|
| Bold silhouette on solid background | Yes | Clear luminance contrast is preserved |
| Thin line art | Partially | Lines may become too subtle under some tint colors |
| Multi-color icon | No | All colors collapse to the single tint hue |
| Gradient fill | Partially | Gradient direction preserved but colors shift |
| Photo-realistic icon | No | Detail is lost when color information is removed |
| Dark icon on light background | Yes | High contrast translates well to any tint |
Apple has also introduced a "dark mode" icon variant for iOS 18 that apps can provide via the asset catalog. For web apps, there is not yet an equivalent mechanism — the apple-touch-icon is always a single static PNG. Watch for changes to this in future Safari updates, as Apple may extend the web manifest or introduce a new link tag to support themed web app icons.
Practical Recommendations
For most sites in 2026, the best approach is to use an SVG favicon as the primary icon (covers all desktop browsers with automatic dark mode adaptation) alongside a static PNG Apple Touch Icon for iOS. The iOS icon does not need dark mode adaptation because iOS renders it against its own themed background on the home screen.
If you are generating favicons with Iconello, the download package includes an SVG that you can modify to add dark mode CSS. Start with the generated SVG, open it in a text editor, add the media query block shown above, and adjust the dark mode colors to complement your brand.
Related Articles
ICO vs PNG vs SVG: Which Favicon Format Should You Use?
A practical comparison of the three major favicon formats. When to use each one, browser support data, and the recommended modern setup.
PWA Icons: Maskable, Adaptive, and Everything in Between
Progressive Web Apps need specific icon formats that regular websites do not. Maskable icons, safe zones, and manifest configuration explained.
What Is a Favicon? The Tiny Image That Makes or Breaks Your Brand
Favicons show up in browser tabs, bookmarks, search results, and mobile home screens. Here is what they are, why they matter, and how to make a good one.