Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails以外の開発一般

2025年のファビコンを極める: 必要なファイルはほぼ3つに減った!(翻訳)

概要

元サイトの許諾を得て翻訳・公開いたします。

日本語タイトルは内容に即したものにしました。

  • 2021/06/24: 初版公開
  • 2024/02/17: 更新版(本記事)を別記事として公開

2025年のファビコンを極める: 必要なファイルはほぼ3つに減った!(翻訳)

はじめに

モダンブラウザで使われるファビコンの作り方を見直して、今こそアイコン生成であくせくするのを終わりにしましょう。昨今のフロントエンド開発者は、ブラウザタブやらタッチ画面やらにWebサイトの小さなロゴを表示する、ただそれだけのためだけに静的なPNGファイルを20個以上扱わなければなりません。よりスマートな方法で、現代のニーズに合う最小限のアイコンセットを使う方法を紹介します。

  • 原編集者メモ(2022): 新年をきっかけに本記事を若干更新し、内容が古びないようにしました。

  • 原編集者メモ(2023): 本記事を再度最新の内容に更新しました。

  • 原編集者メモ(2024): 記事を全面的にチェックして最新の内容に更新しました。

  • 原編集者メモ(2025): 最新の内容をチェック済みです。自信を持ってファビコンを扱いましょう!

ファビコン(favicon)は見かけよりもずっと幅広く奥深いトピックで、実は誰もがファビコンについてしっかり学びたいと思っていることもわかってきました。本記事全体の内容を実質わずか2行のスニペットに凝縮したものも紹介していますので、今ファビコンで苦しんでいる方は(正確な使い方をご存知なら)そちらをお使いいただけますが、そこをぐっとこらえて記事を最後までお読みいただくことをおすすめいたします。

🔗 忙しい人向け: ウルトラショート版解説

苦労してアイコンを10個以上用意しなくても、以下のように5個のアイコンとJSONファイル1個があればできます。

ブラウザ用HTMLに以下のように書きます。

<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png"><!-- 180×180 -->

PWA(Progressive Web App)を作成しているなら、上のHTMLに以下も追加し、

<link rel="manifest" href="/manifest.webmanifest">

続いてWebアプリのマニフェストJSONファイルにも以下のように書きます。

// manifest.webmanifest
{
  "icons": [
    { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
    { "src": "/icon-mask.png", "type": "image/png", "sizes": "512x512", "purpose": "maskable" },
    { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
  ]
}

maskable(マスク可能)なアイコンでは、パディングを多めにする 必要があります。アイコンのセーフゾーン(safe zone)は409×409の円内です。
以下のアプリでアイコンのマスキングを確認できます。

参考: Maskable.app


これで完了です。私がこの方法にたどり着くまでの経緯や妥協しなければならなかった点、および手順を追ってゼロから行う方法を学びたい方は、ここから先へお進みください。

🔗 完全版解説

"完璧の域に達するのは、付け足すものがなくなったときではなく、削るところがなくなったときである。"
アントワーヌ・ド・サン=テグジュペリ『Airman's Odyssey』(日本語未訳)

ファビコン(favicon: favorite iconの略)という概念が登場したのは2000年代初頭のことです。ブラウザのタブバーにいつも可愛らしい画像がちっちゃく表示されて、現在開いているWebサイトを区別できるようにしているのを誰もが目にしています。ユーザーはWebサイトにファビコンがあるのが普通だと考えているものです。一見ささいなことに思えますが、ファビコンは大事だと考える人は世の中にたくさんいるのです。

Appleはこれまでずっと、自社以外のアイコンが表示されるのは審美的によろしくないとばかりにSafariのファビコン表示をぞんざいに扱っていましたが、そのAppleですら今や自社の全デバイスでファビコンを正しく表示するようになりました。


一般に公開するWebサイトを運営するなら、ファビコンをちゃんと用意しなければなりません。ユーザーから見えるアイコンはたった1個なのに、実際には複数のアイコンが必要とされています。


そういうわけで、種類が増え続ける画面やデバイスに対応するアイコンファイルを生成するという面倒な作業には、ファビコン生成ツールを用いるのが一般的です。まともな人ならファビコンごときに数時間もかけたくないでしょう。私たちはWebサイトを作ろうとしているのであって、ブラウザベンダーを喜ばせるために仕事をしているのではありません。

有名なファビコン生成サイトで生成した大量のファビコンファイル

私はNanoIDの作者として、また「ミニマルなオープンソース」の提唱者として、物事をやや別の側面から考えるところがあります。Webサイトで最も効率のよいアイコンセットとはどんなものでしょうか?時代遅れになったファイルフォーマットはどれでしょうか?少々の妥協と引き換えに置き換えても大丈夫なアイコンはどれでしょうか?

そこで私は、わずかな例外を除けばあらゆるブラウザで正しく表示される最小限のファビコンリストを作ることにしました。100%完璧とまではいかなくても、表示は引き続き可能です。

🔗 究極のファビコンリストをセットアップする

私は、大きさの異なる画像ファイルを大量に作るのをやめて、SVG画像とブラウザの画像縮小機能を頼りにすることに決めました。そんなことをしたらパフォーマンスが落ちるのではとご心配の方へ: ここで皆さんの誤解を解いておきたいと思います。

  • ブラウザはファビコンをバックグラウンドでダウンロードします。
    したがって、ファビコン画像はWebサイトのパフォーマンスに影響しません。
  • SVGフォーマットは、元がビットマップでない画像のサイズを縮小するのに適しています。
    「たいていの」ロゴはPNGよりもSVGの方がずっとサイズが小さくなります。
  • 最小限のファイルセットに含まれるPNG画像は3つだけ含まれていて、高度なツールを用いて画像サイズを最適化できます。
    これにより、ネット接続が無制限プランでないネットユーザーの問題を解決できます。

私がこれまで研鑽と実践を重ねてきた最小限のアイコンセットを以下に包み隠さず公開いたします。メジャーなブラウザやデバイスであれば、新旧を問わず正しく表示できるはずです。

🔗 1. favicon.ico(レガシーブラウザ用)

ICOファイルは一見ファイルのようですが、実際にはディレクトリ構造があり、解像度の異なるさまざまなファイルをその中に保存できます。

ICOファイルのサイズは、16×16表示のアイコンがぼやけてしまうといった問題が生じない限りは、32×32画像1個だけにしておくことをおすすめします。そのうえで、この小さいサイズで正しく表示できる特別なロゴを改めてデザイナーに依頼しましょう。

このとき、ICOファイルをわざわざ静的アセット用ディレクトリに置いたり、キャッシュバスターを使ったりするなどの小細工を行わないこと。https://example.comというWebサイトであれば、素直にhttps://example.com/favicon.icoに置いてください。RSSリーダーなど一部のツールはサーバーの/favicon.icoにしかリクエストを送信せず、それ以外の場所にファビコンがあるかどうかをわざわざ探そうとしません。

ChromeでSVGではなくICOファイルが選択されるバグ↓を修正するには、.icoファイルを指定する<link>sizes="32x32"を書く必要があります。

🔗 2. ライト/ダークモード対応のSVGアイコン(モダンブラウザ用)

SVGファイルは、ピクセルではなく曲線を記述するベクタ形式です。SVGはサイズが大きくなるほど、いわゆるラスター画像よりも効率が高まります。本記事執筆時点では、全ブラウザの72%がSVGアイコンをサポートしています(caniuse.com)。

HTMLページの<head>セクション内に<link>タグを追加し、その<link>タグにrel="icon"属性とtype="image/svg+xml"属性を指定したうえで、SVGファイルへのリンクをhref属性で指定する必要があります。

SVGファイルはXMLフォーマットになっていて、その中にCSS記述用の<style>タグが含まれています。普通のCSSを使う場合と同様、ここにも@media (prefers-color-scheme: dark)のようなメディアクエリを書けます。こうすることで、同じアイコンをダークテーマとライトテーマに応じて切り替えられます(参考:『prefers-color-scheme in SVG favicons for dark mode icons』)。

🔗 3. 180×180 PNG画像(Appleデバイス用)

Appleの「タッチアイコン(touch icon)」は、iPhoneやiPadのホーム画面上にWebページを追加したときに表示される、Apple製デバイス用の画像です。この場合、HTMLの<head>セクション内に<link rel="apple-touch-icon" href="apple-touch-icon.png">というタグを置く必要があります。

この画像は、iOS 8以降のiPadでは180×180の解像度が必要ですが、その他のデバイスでは画像が縮小されます。ただし、縮小に耐える十分な品質の画像を使っていれば、画像が縮小されてもユーザーには影響しません(後述)。

メモ: Appleのタッチアイコン画像の周囲にパディングを20px確保し、背景にも色を付けておけば、アイコン表示がより整います。タッチアイコンはどんな画像編集ソフトでも問題なく扱えます。

🔗 4. Webアプリマニフェスト + 192×192 PNGアイコン + 512×512 PNGアイコン(Android用)

  • WebアプリマニフェストはJSONファイルで、Webサイトをシステムアプリケーションとしてインストールするときにブラウザが用いる詳細情報がすべて保存されます。このフォーマットの由来は、GoogleのPWA(Progressive Web Application)イニシアティブです。

  • これを用いるには、HTMLファイルに<link rel="manifest" href="webmanifestへのパス">タグを追加して、マニフェストファイルへのリンクを記述する必要があります。

  • マニフェストファイルには、以下の3つのアイコンにリンクするiconフィールドが必要です。

    • ホーム画面に表示される192×192のアイコン
    • さまざまなAndroidランチャー用の512×512のマスク可能なアイコン
    • PWAの読み込み中にスプラッシュ画面として使われる512×512のアイコン
  • マスク可能なアイコンは、ランチャーでデザインに合わせて切り取られてもいいように、アイコンの周囲に多めのパディングが必要です。セーフゾーンは、中央の409×409の円内です。maskable.appを使うことでアイコンの表示を確認できます。

{
  "icons": [
    {
      "src": "/icon-192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "/icon-mask.png",
      "type": "image/png",
      "sizes": "512x512",
      "purpose": "maskable"
    },
    {
      "src": "/icon-512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ]
}

🔗 何か忘れてない?

はい、もちろんこれ以外にもファビコン関連のファイルはたくさんありますし、中にはろくに知られていないものもあります。日の目を見なかったファビコンフォーマットたちにそろそろさよならを言うときが来たようです。

🔗 Windowsのタイルアイコン

Microsoft Edgeではかつて、タイルアイコンという特殊なアイコンフォーマットがサポートされていたことがあり、Webサイトをスタートメニューに固定するのに用いられていました。しかし最近のWindowsではこのアイコンは不要になりました。

🔗 Safariのタブ固定時アイコン

以前のSafariでも、タブ固定時に表示するモノクロのSVGアイコン(pinned icon)が別途必要とされていました。しかしSafari 12以降はタブ固定時アイコンで普通のファビコンを使えるようになりました。今や本家apple.comでもmask-iconは使われていません。

🔗 rel="shortcut"

世の中には、未だに「HTMLにfavicon.icoを含めるときは以下のようにしましょう」という化石のような知識を教えるチュートリアルが山ほどあります。

<link rel="shortcut icon" href="/favicon.ico" sizes="32x32">

ぜひともご注意ください。このshortcutというリンク種別は今やまったく無効です。詳しくはMathias Bynensが10年も前に書いた素晴らしい記事『rel="shortcut icon" considered harmful · Mathias Bynens』には、shortcutが完全に不要である理由と、rel="icon"で十分な理由が説明されています。

icon より以前はリンク種別 shortcut がよく使用されていましたが、これは非準拠で無視されますのでウェブ作者は今後使用してはいけません。
リンク種別 - HTML: HyperText Markup Language | MDNより

🔗 Opera Coastブラウザ

Opera CoastというiOS向けの実験的ブラウザでは、228×228という特殊なサイズのアイコンが必要だった時期がありました。このブラウザは2017年にApp Storeから姿を消しています。その後に何度もアップデートされたiOSでこのブラウザが果たして動くかどうかも怪しいところです。


さて、累々と横たわる戦友たちにこの辺で別れを告げることにして、今度は今も戦い続けているブラウザたちのために究極のファビコンセットの作り方を見ていくことにしましょう。

🔗 究極ファビコンセットの作り方

ここからは、究極のファビコンミニマムセットを6つの簡単なステップで手軽に作る方法をご紹介します。必要なのは、ファビコンに使いたいSVGファイル1個だけです。

🔗 ステップ1: SVGファイルを準備する

SVG画像は必ず「正方形」にしてください。画像をシステムのビューアで開いて、高さと幅が正方形になっているかどうかを確かめておきましょう。SVGエディタなら簡単に調整できます。

InkscapeからダウンロードできるInkscapeアプリでSVGファイルを開き、「ファイル > ドキュメントのプロパティ」メニューでドキュメントのサイズを変更し、「オブジェクト > 整列と配置」メニューでロゴを中央揃えにできます。

このファイルをicon.svgという名前で保存します。続いて、このSVGファイルに手を加えて最新のシステム「テーマ」に対応させましょう。ダークテーマで色をどのような形で反転すべきかについて、デザイナーに問い合わせておいてください(白黒のロゴなら単純に白黒反転するだけでよいでしょう)。

反転方法が決まったら、いよいよSVGファイルを「テキストエディタ」で開きます。fillがダークテーマ用になっている<path>タグ(またはfillがない<path>タグ)を探します。以下のようにシステムテーマ変更時にトリガーするCSSメディアクエリを<style>タグで追加し、fillの色指定を自分が使いたい色に変更します。

  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
+   <style>
+     @media (prefers-color-scheme: dark) {
+     .a { fill: #f0f0f0 }
+     }
+   </style>
-   <path fill="#0f0f0f" d="..." />
+   <path class="a" fill="#0f0f0f" d="..." />
  </svg>

color-gamut: p3メディアクエリを利用して広色域P3をSVGに追加することも可能です(以下の記事を参照)。

🔗 ステップ2: ICOファイルを作成する

このicon.svgファイルを、ラスター画像エディタで開きます(個人的には無料かつマルチプラットフォームのGIMPがおすすめです)。

レンダリング方法をSVGからラスターに変更し、幅と高さを32ピクセルに設定したら、favicon.icoというファイル名でエクスポートします。このときに「32 bpp, 8-bit alpha, no palette」を指定します。

GIMPをお持ちでない場合は、以下のようにターミナルでInkscapeImageMagickを使えばSVGをICOファイルに変換できます。

inkscape ./icon.svg --export-width=32 --export-filename="./tmp.png"
# Windowsの場合以下を`magick convert ./tmp.png ./favicon.ico`にする
convert ./tmp.png ./favicon.ico
rm ./tmp.png

訳注

ImageMagickのバージョンの注意点について、「convertコマンドの使い方: UNIX/Linuxの部屋」より引用します。

●ImageMagick バージョン7 以降の注意点
ImageMagick バージョン7 より、convert 等のコマンドがなくなり magick コマンドに変更されている。Windows で関係ない convert コマンドが存在し、混乱を招くため。2017年9月現在、FreeBSD では ImageMagick がバージョン6、ImageMagic7 がバージョン7 として ports/packages が用意されている。
同記事より

次に変換で作成したfavicon.icoファイルの画像サイズを16×16に縮小して表示を確かめます。画像がぼやけてしまう場合は、デザイナーに依頼して小さな表示に最適化したロゴも作ってもらうことをおすすめします。

favicon.icoに16×16版のアイコンも含めるには次のようにします。

  1. アイコンサイズが32×32のfavicon.icoファイルを開く。
  2. 16×16版アイコン用のレイヤを1つ追加する。
  3. このレイヤに16×16版のアイコンを貼り付ける。
  4. ファイルにエクスポートする(GIMPは、異なるICONバージョンを個別のレイヤに保存します)。

なお、以下のようにImageMagickのコマンドを用いても同じ結果が得られます。

convert ./icon-32.png ./icon-16.png ./favicon.ico

🔗 ステップ3: PNG画像を作成する

元のSVGファイルを再びラスター画像エディタで開いて、512×512の画像を作成し、icon-512.pngというファイル名でエクスポートします。

次に同じ画像のサイズを192×192に変換したものも作成し、icon-192.pngというファイル名でエクスポートします。

次にその画像自体のサイズを140×140に変換し、さらにキャンバスのサイズを180×180に拡大したうえで、apple-touch-icon.pngというファイル名でエクスポートします。

次に、その画像を409×409に拡大し、キャンバスを512×512に拡大して、icon-mask.pngというファイル名でエクスポートします。

maskable.appでさまざまなマスクを適用してアイコンの表示を確認し、必要に応じてアイコンのサイズを調整します。

以下のようにinkscapeコマンドを用いても同じ結果が得られます。

inkscape --export-type="png" --export-width=512 --export-filename="./icon-512.png" ./icon.svg
inkscape --export-type="png" --export-width=192 --export-filename="./icon-192.png" ./icon.svg

🔗 ステップ4: PNGファイルとSVGファイルを最適化する

訳注

ここで言う最適化は、画像ファイル容量の縮小を指します。

SVG最適化ツールはSVGOがベストです。ターミナルで以下のコマンドを実行するだけで完了します。

npx svgo --multipass icon.svg

svg/svgo - GitHub


Squooshは、ラスター画像の最適化に適しているWebアプリです。

  1. Sqooshサイトにicon-512.pngをアップロードまたはドロップします。
  2. 圧縮設定をOxiPNGに変更します。
  3. "Reduce palette"を有効にします。
  4. その下の"colors"を64に設定します。
  5. ブラウザの真ん中にあるスライダーを左右に動かして変更前/変更後を比較します。色味が変わっていたら、"colors"の色数を増やします。
  6. ファイルを保存します。

icon-192.pngapple-touch-icon.pngについても上のステップを繰り返します。

🔗 ステップ5: HTMLにアイコンを追加する

favicon.icoへのリンクとapple-touch-icon.pngへのリンクをHTMLに追加する必要があります。

静的HTMLでは以下のように追加します。

  <title>My website</title>
+ <link rel="icon" href="/favicon.ico" sizes="32x32">
+ <link rel="icon" href="/icon.svg" type="image/svg+xml">
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png">

しかし、このときに何らかのバンドラー機構を用いて「キャッシュバスター」を生成しておくことをおすすめします(つまりファイル名に846acd9bc30aのようなハッシュを含めてフィンガープリントとして使います)。Webpackでhtml-webpack-pluginを使っている場合は、以下の手順でできます。

  • 1: index.htmlテンプレートを作成します。
  • 2: テンプレートに以下のプラグインオプションを追加します。
new HtmlWebpackPlugin({ template: "./view/index.html" });
  • 3: リンクを含むHTMLテンプレートを定義します。以下の例ではHtmlWebpackPluginでファイルをインクルードしていますが、今使っているテンプレート言語でも大丈夫です。
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>My website</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="icon" href="/favicon.ico" sizes="32x32">
    <link rel="icon" type="image/svg+xml" href="<%=
      require('./icon.svg').default
    %>">
    <link rel="apple-touch-icon" href="<%=
      require('./apple-touch-icon.png').default
    %>"
   >
  </head>
  <body></body>
</html>
  • 4: favicon.icoをコピーするときは、copy-webpack-pluginを使うことでファイル名にハッシュを手動で追加せずに済みます。

🔗 ボーナス: stagingで別のアイコンを使う技

ファビコンは、環境がproductionかstagingかを区別するにも便利です。staging環境のアイコンを別のものに変えておくと、productionとstagingを取り違えて痛い目に遭わないための対策として非常に有効であることに気づきました。

ICOファイルの色だけを反転させたfavicon-dev.icoファイルを作成します(ひと目で区別が付けば他の方法でも構いません)。同様にSVGファイルについても色を反転させたicon-dev.svgファイルを作成します。

そして、process.env.NODE_ENV === 'production'条件に応じてHTMLテンプレート内のアイコンを差し替えます。

  <!doctype html>
  <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>My website</title>
      <meta name="viewport" content="width=device-width,initial-scale=1">
-     <link rel="icon" href="/favicon.ico" sizes="32x32">
+     <link rel="icon" sizes="32x32" href="<%=
+       process.env.NODE_ENV === 'production'
+         ? '/favicon.ico'
+         : require('./favicon-dev.ico').default
+     %>">
      <link rel="icon" type="image/svg+xml" href="<%=
-       require('./icon.svg').default
+       process.env.NODE_ENV === 'production'
+         ? require('./icon.svg').default
+         : require('./icon-dev.svg').default
      %>">
      <link rel="apple-touch-icon" href="<%=
        require('./apple-touch-icon.png').default
      %>">
    </head>
    <body></body>
  </html>

🔗 ステップ6: webアプリのmanifestを作成する

静的HTMLの場合は、以下のmanifest.webmanifestというJSONファイル名を作成します。

{
  "name": "My website",
  "icons": [
    { "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
    { "src": "/icon-mask.png", "type": "image/png", "sizes": "512x512", "purpose": "maskable" },
    { "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" }
  ]
}

次にHTMLにリンクを追加します。

  <title>My website</title>
+ <link rel="manifest" href="/manifest.webmanifest">
  <link rel="icon" href="/favicon.ico" sizes="32x32">
  <link rel="icon" href="/icon.svg" type="image/svg+xml">
  <link rel="apple-touch-icon" href="/apple-touch-icon.png">

Webpackを使っている場合は、webpack-pwa-manifestプラグインを利用できます。

  plugins: [
    ...,
    new WebpackPwaManifest({
      name: 'My website',
      icons: [
        { src: resolve('./icon-192.png'), sizes: '192x192' },
        { src: resolve('./icon-mask.png'), sizes: '512x512', purpose: 'maskable' },
        { src: resolve('./icon-512.png'), sizes: '512x512' }
      ]
    })
  ]

お読みいただいた皆さんに感謝です。ご覧いただいたように、モダンなWeb標準を活用したことで、究極のファビコンセットをとてもシンプルに作成できるようになりました。紹介した手順は手動で進めてもさほど手間ではありませんが、同じことを自動化ツールでできればさらに便利でしょう。我こそはとお思いの方がいらっしゃいましたら、Twitterの@sitnikcodeまでお知らせいただければ喜んでお手伝いいたします。

🔗 Changelog

2024-09-05
PWA用のマスク可能アイコンの記述を追加
2023-11-19
ICOとPNG生成のCLIコマンドを修正
2023-07-11
ICOファイルのsizes="any"sizes="32x32"に置き換え(ChromeでICOとSVGを両方ダウンロードするバグを修正)
2021-07-19
ICOファイルにsizes="any"を追加(ChromeがSVGではなくICOファイルをダウンロードするバグを修正)
2021-01-19
SVGをPNGに変換するInkscapeコマンドを追加
2021-01-15
ImageMagickコマンドを追加(GIMPを持っていないユーザー向け)

Designed and developed by Evil Martians

関連記事

保存版: Web画像フォーマットを「正しく」扱う(3)Evil Martians流巨大画像圧縮クックブック(翻訳)

UIデザインで役立つ「不透明度」使いこなしガイド(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。