🎨

Favicon の色を動的に変えてみよう!

2024/10/11に公開

ライトモードとダークモードで切り替わる例

例えば GitHub なんかは、ライトモードで見てるかダークモードで見てるかによって Favicon の色が変わる。

ページごとに切り替わる例

SHURO という漫画サイトでは、(たぶん)作品によって Favicon の色が変わる。

例えば「そうです、私が美容バカです。」では水色の Favicon になる。

そして「恋とか夢とかてんてんてん」では緑色の Favicon になる。

Favicon の色を変えてみよう!

見てわかるように Favicon の色が変わるとなんかかっこいいので、変えてみる。

.ico ファイルを JavaScript で動的に差し替える方法もあると思うけれども、せっかくなので今回は SVG Favicon を使ってみる。
Safari は未だに SVG Favicon に対応していないが…

https://caniuse.com/link-icon-svg

SVG Favicon の準備

とりあえずシンプルに丸い SVG を用意する。

<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
  <circle cx="8" cy="8" r="8" fill="#000000" />
</svg>

これを Base64 Encode してこんな感じの HTML を書いてあげると、SVG が Favicon になる。

    <link
      rel="icon"
      href="data:image/svg+xml;base64,PHN{略}Zz4="
      sizes="any"
      type="image/svg+xml"
    />

この時点では真っ黒な丸が Favicon になっているだけで、あまり楽しくないので色を変えたい。

色の変え方

せっかくなので OKLCH でアクセスした時間帯によって色が変わるようにしてみる。

要は circlefill を変えるだけでいい。

css

:root {
  --hue: 235;
  --accent-color: oklch(37% 0.16 var(--hue));
}

js

  const date = new Date();
  const seconds =
    date.getSeconds() + 60 * date.getMinutes() + 60 * 60 * date.getHours();
  const hue = (Math.round(seconds / 240) + 235).toString();
  document.documentElement.style.setProperty("--hue", hue);

  window.onload = () => {
    const faviconSvg = `<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"><circle cx="8" cy="8" r="8" fill="${window.getComputedStyle(document.documentElement).getPropertyValue("--accent-color")}" /></svg>`;
    const linkSvgFavicon = document.querySelector(
      "link[rel='icon'][type='image/svg+xml']",
    );
    linkSvgFavicon?.setAttribute(
      "href",
      `data:image/svg+xml;base64,${btoa(faviconSvg)}`,
    );
  };

結果

記事執筆時点で自分のサイトにこの実装を入れている。

https://studio15.jp/

20 時頃にアクセスしたら緑色の Favicon になった。

24 時くらいにアクセスすると青色の Favicon になるはず。

See also

https://hail2u.net/blog/mozoushi.html

Discussion