アイコンフォントか? SVG アイコンか?

この記事は、「Web Accessibility Advent Calendar 2015」の17日目のエントリーです。


ウェブデザインにおいて、アイコンを配置することは多いと思います。特にここ数年はアイコンフォントを採用する案件が個人的に多かったこともあり、「アイコンフォントのアクセシビリティ向上」という記事を書いたりもしました。

ところがアイコンフォントにはもっと根本的なアクセシビリティ問題があるという指摘もあります。たとえば以下の記事が参考になるでしょう。

総じて言うと、アイコンフォントは、本来テキスト (文字情報) を表現するための仕組みを「ハック」して (Unicode の私的領域を使って) 視覚的なシンボルを表現するものであるため、以下のリスクがある、というのです。

前者 (スクリーンリーダーでアイコンの情報が適切に読み上げられない) については、「アイコンフォントのアクセシビリティ向上」にも書いたとおり、そのアイコンに代替テキストが必要であれば aria-label でラベルを記述する、そのアイコンが装飾的なものであれば aria-hidden="true" を記述してスクリーンリーダーに無視させる、という形で解決できそうです。一方、後者 (アイコンフォントが表示されない) については、どうしたらよいでしょうか。

アイコンフォントが表示されないリスクを考える

上述の「Seriously, Don’t Use Icon Fonts - Cloud Four Blog」によると、たとえばユーザーがウェブサイトのフォントを OpenDyslexic に置き換えたりすることで、アイコンフォントが化ける (「豆腐」になる) 可能性が指摘されています。もっとも「OpenDyslexic だから問題が生じる」わけではなく、OpenDyslexic であっても Chrome 拡張機能を介して適用すればアイコンフォントの表示は維持されたりもするので、どちらかと言うと、フォントの種類というよりはフォントをカスタマイズする手段によるものなのかなと思われます。

発生頻度としては多くないのかもしれませんが、ユーザーによるフォントのカスタマイズ設定によってアイコンフォントが表示されない可能性があること、そして、もしそうなった場合、アイコンを介して伝わるべき情報がユーザーに適切に伝わらないリスクがあることは、念のため気に留めておいたほうがよいかもしれません。特にアイコン単体で (ラベルを伴わない形で) 機能説明など重要な情報を伝達する場合、要注意と言えるでしょう。

SVG アイコンを検討する

アイコンフォントが持つ利点 (画像アイコンと異なりベクターデータなので、高解像度の画面で表示したり拡大したりしてもジャギーにならずきれいに表示される) を活かしつつ、それでいてアイコンフォントに潜むリスク (フォント設定のカスタマイズによって表示されない可能性がある) を回避するには、代わりに SVG アイコンを用いるという手があります。

SVG アイコンをウェブページ上で表示する方法としては以下が挙げられますが ;

CSS によるアイコンのスタイル制御 (たとえば、ボタンが押されたり、キーボード操作のフォーカスを受け取ったり、といった状態の変化に応じて色を変える) のしやすさ、という観点で考えると、インライン SVG に分があると言えるかもしれません。<img> 要素や CSS background-image で .svg ファイルを読み込む形だと、状態に応じてアイコンの色などを変える場合、状態ごとに .svg ファイルを用意して差し替える実装になるため、アセット管理が煩雑になりそうです。さらに、もしもダークモード対応をしようものなら、モード (テーマ) ごとに各状態の .svg ファイルを用意しなければならないでしょう。

また、Windows の「ハイコントラスト」モードにおいてもアイコンの視認性を保つ、という観点で考えても、<img> 要素や CSS background-image での .svg ファイルの読み込みは、注意が必要です。アイコンの描画以外の部分が透明の場合、「ハイコントラスト」によって背景色が変わると、アイコン自体が見えなくなる (あるいは見にくくなる) 恐れがあるからです。

インライン SVG であれば CSS による色の制御が可能なので、たとえば以下のように、そのアイコンが配置されているエリアに適用されている CSS の color に連動させる形で、「ハイコントラスト」モード時の視認性を担保する、といったことができます。


<svg>
  <path fill="current-color"></path>
  <style>
    @media(forced-colors: active) {
      path { forced-color-adjust: auto; }
      }
  </style>
</svg>

なお以前であれば、Windows の「ハイコントラスト」モードが有効になると、IE において CSS background-image による背景画像が非表示になってしまう現象が見られましたが、Edge になって以降は、「ハイコントラスト」モードであっても背景画像は維持されるようになっているようです。

アイコンフォントと SVG アイコンの使い分け

以上を踏まえ、アイコンフォントと SVG アイコンをどう使い分けるかを考えてみたいと思います。たとえば以下のように、「ラベルを伴うアイコン」と「ラベルを伴わないアイコン」という切り分けで、考えてみるのはいかがでしょうか。

ラベル (テキスト) を伴うアイコンの場合
アイコンフォント、SVG アイコン、どちらを採用してもよい。肝心な情報はテキストラベルで伝え、仮にアイコンが見えなくてもユーザーの利用に大きな支障がないようにする。アイコンフォントであれば、テキストとして CSS によるスタイリングができるので、色や大きさの指定など、テキストラベルとスタイルを合わせやすいという利点がある。なお多くの場合、ラベルを伴うアイコンはアイキャッチの装飾であると想定されるが、その場合はスクリーンリーダー利用者にとっての情報ノイズを軽減するため、アイコンの要素に aria-hidden="true" を適用する。
ラベルを伴わない (それ単体で UI 部品として成り立つ) アイコンの場合
SVG アイコン (インライン SVG) を採用し、svg 要素には role="img" を記述し、aria-label などで代替テキストを付与する。アイコンフォントはユーザーによるフォントのカスタマイズ設定によって見えなくなるリスクがあること、また <img> 要素を用いた .svg ファイルの配置では CSS によるスタイル制御の難しさや「ハイコントラスト」モード時に見えなくなるリスクがあることに留意する。

以上、唯一の正解ではありませんが、ひとつの考えかたとして参考になれば幸いです。