ダークモード対応favicon: テーマに追従するアイコンを作る
濃紺のマークは、暗いタブバーの上では見えなくなってしまいます。1つのSVGでも、2つのPNGでも解決できますが、いずれの場合も下地にデフォルトのアイコンを残しておきます。
ダークモードで実際に変わるもの
ブラウザのタブバーは、ライトモードでは明るく、ダークモードでは暗くなります。faviconは、変わるように作らない限り、それに合わせて変化しません。白の上では鮮明に見えるマークも、ほぼ黒に近いタブの上では消えてしまうことがあり、明るいマークと明るいchromeの組み合わせでも逆のことが起こります。
対応する方法は2つあります。自身の色を塗り替えるSVGを1つ配信するか、2つのPNGを配信してOSの設定に基づいてブラウザに選ばせるかです。SVGの方法はファイル1つ、リクエスト1つで済みます。PNGの方法はより多くのクライアントで動作しますが、media切り替えのfaviconへの対応は不均一なので、フォールバックに頼る場面がより多くなります。
方法A: 自身で切り替わる1つのSVG
SVG faviconは自前のCSSを持つことができます。prefers-color-scheme: darkのmedia queryをSVG内に置き、そこでfillを変更します。ブラウザはOSの設定を読み取り、2つ目のファイルも追加のlinkタグもなしにアイコンを再描画します。
これが最初に検討すべき方法です。ファイルは1つ、どのサイズでも鮮明さを保ち、単一のアセットで両方のテーマをカバーできる唯一のアプローチです。
SVGとフォールバック
<!-- In your <head>: SVG first, then the raster fallback -->
<link rel="icon" type="image/svg+xml" href="/icon.svg">
<link rel="icon" href="/favicon.ico" sizes="any">
<!-- icon.svg, with the theme rule baked in -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<style>
path { fill: #1a1a1a; }
@media (prefers-color-scheme: dark) {
path { fill: #f5f5f5; }
}
</style>
<path d="M6 6h20v20H6z" />
</svg>SVGを読めるブラウザは1行目を使い、media queryを尊重します。それ以外はすべてfavicon.icoにフォールバックします。
方法B: media指定したlinkタグ上の2つのPNG
SVGが使えない場合は、2つのPNG(たとえば明るい背景に暗いマークのバージョンと、暗い背景に明るいマークのバージョン)を書き出し、それぞれのlinkタグにmedia属性でヒントを与えます。ブラウザは現在のテーマに一致するものを読み込みます。
これへの対応はまちまちです。一部のブラウザはアイコンのlinkにあるmedia属性を無視し、理解できた最初のものをそのまま採用します。だからこそ最後の行が重要になります。media条件のない素のfavicon.icoは、どんなクライアントでもフォールバックできるデフォルトです。
2つのPNGの構成
<link rel="icon" type="image/png" href="/favicon-dark.png"
media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" href="/favicon-light.png"
media="(prefers-color-scheme: light)">
<link rel="icon" href="/favicon.ico" sizes="any">無条件のfavicon.icoを最後に置いておくことで、mediaヒントを無視するブラウザでもアイコンが表示されます。
とりあえず動く手軽な方法
ここまでの手間をかける価値がないなら、中間色のマークを1つ使いましょう。明るいchromeでも暗いchromeでも読めるだけの十分なコントラストを持つ色(ほぼ黒でもほぼ白でもない、彩度の高いブランドカラー)なら、単一のファイルで両方のテーマで判読できます。
これが実用的なデフォルトです。各テーマへの完璧な一致は失いますが、決して消えない1つのアセットと、間違えようのないmedia条件のなさが手に入ります。
よくある質問
faviconをダークモードで変えるにはどうすればいいですか?
スタイル内にprefers-color-scheme: darkのmedia queryを持たせてfillの色を切り替えるSVG faviconを使うか、media指定したlinkタグ上に2つのPNGを配信します。いずれの場合も、素のfavicon.icoをデフォルトとして残しておきます。
ダークモード対応faviconはすべてのブラウザで動きますか?
内部にmedia queryを持つSVG faviconは、モダンブラウザで十分に対応されています。media切り替えのPNG faviconはあまり信頼できないので、常に無条件のフォールバックアイコンを含めておきましょう。
ダークモードを省いてfavicon1つで済ませられますか?
はい。明るいタブでも暗いタブでも読めるだけの十分なコントラストを持つ中間色のマークを選びましょう。ファイルは1つで、どちらのテーマの上でも決して消えません。
favicon.icoはダークモードのために変える必要がありますか?
いいえ。favicon.icoは、古いクライアントやクローラー向けのデフォルトのフォールバックです。判読できる1つのバージョンとして残しておき、テーマの切り替えはその上のSVGやPNGのlinkで扱いましょう。