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

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


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

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

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

前者 (スクリーンリーダーで適切に読み上げられない) については、「アイコンフォントのアクセシビリティ向上」にも書いたとおり、そのアイコンに代替テキストが必要であれば「aria-label」でラベルを記述する、そのアイコンが装飾的なものであれば「aria-hidden="true"」を記述する、という形で解決できそうです (私自身の経験は Font Awesome に限られますが、所定の <i> 要素にこれらの WAI-ARIA 属性を追記すれば、NVDA、VoiceOver、TalkBack といったスクリーンリーダーでは特に問題ありませんでした)。一方、後者 (アイコンフォントが表示されない) については、どうしたらよいでしょうか。

アイコンフォントが表示されないリスクは高いのか?

アイコンフォントが表示されない状況は、案外簡単に引き起こすことが可能です。以下の操作 (フォント設定のカスタマイズ) をしたうえで、実際に Font Awesome などアイコンフォントが実装されているサイトを開いてみると体感できます。

Internet Explorer (IE)
インターネットオプションの「全般」タブを開き、「デザイン」セクションの「フォント」で任意のフォントを選択する。そのうえで、同「デザイン」セクションの「ユーザー補助」で「Web ページで指定されたフォント スタイルを使用しない」を選択する。
Chrome (Windows および OS X)
アドオン「Font Changer」を使って任意のフォントを選択する。

ただし、フォント設定のカスタマイズが、必ずしもアイコンフォントの非表示を引き起こすとは限らず、たとえば Chrome や Firefox に標準装備されているフォントのカスタマイズ機能では、アイコンフォントへの影響はありません (私自身、Font Awesome のサイトを実験台に試してみましたが、アイコンフォントの表示は特に問題なく維持されました)。

余談ですが、「Seriously, Don’t Use Icon Fonts - Cloud Four Blog」を読むと、OpenDyslexic フォントの適用でアイコンフォントが化ける (「豆腐」になる) 旨の記述がありますが、実際には「OpenDyslexic だから問題が生じる」 わけではありません。OpenDyslexic であっても、専用の Chrome アドオンを使って適用すると、アイコンフォントの表示は維持されます。フォント設定のカスタマイズにおいて「どのフォントを選ぶか」が問題なのではなく、「どんな手段でカスタマイズするか」が問題なのでしょう。

これらの事象をもとにリスクの高さをどう捉えるかですが、発生頻度としてはそう多くなさそうなものの、一部のユーザー環境では簡単に発生し得る (しかも発生した場合、アイコンを介して伝えたい情報がユーザーに正しく伝わらない) こともあり、低リスクであると言い切るのは難しそうです。特に、アイコン単体で (隣接するラベルを伴わない形で) ボタンなどの UI 部品を形成するようなケースでは要注意と言えるでしょう。

アイコンフォントの代わりに SVG アイコンを用いる

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

SVG をウェブページ上で表示する方法はいろいろありますが、アイコン程度の用途であれば、.svg ファイルを <img> 要素で配置する形で十分でしょう (代替テキストも alt 属性で付与できます)。隣接するラベルがあって、その装飾のためだけにアイコンを用いるのであれば、CSS の background-image プロパティで配置することもできます。

もちろん、HTML 内に直接 SVG のソースを記述する手もありますが (インライン SVG)、インフォグラフィックのようなものならともかく、アイコン程度の用途の場合、HTML ソースを必要以上に複雑にしてしまうような気がします。

SVG アイコンにも短所はある

ただ、SVG アイコンにも短所はあります。アイコンフォントに比べて、SVG アイコンは以下が残念だなと思います。

フォーカス時に色だけを変更することが (インライン SVG でないと) できない

アイコンフォントは HTML テキストの一部という扱いになるので、CSS の color プロパティで色をコントロールすることができます。たとえばリンクラベルとアイコンが一組になっているようなケースで、<a> 要素に対して :focus 疑似クラスで color プロパティを指定しておくと、フォーカス時に、テキストとアイコンの色が一緒くたに変更されるので、制作する側としては楽です。

これに対し SVG は、インライン SVG でないと CSS で色 (fill 属性) をコントロールすることができないようです。<img> 要素や CSS (background-image) によって SVG アイコンを配置している場合、フォーカス時にアイコンの色を変更するには、色違いの別の SVG アイコンに差し替える必要があり、「SVG スプライト」という手法はあるものの、アイコンフォントよりは実装が面倒です。

Windows のハイコントラストモードに弱い

アイコンフォントは HTML テキストの一部という扱いになるので、Windows でハイコントラストモードにすると、IE の画面上において文字色と同じ配色になります。アイコンが見にくくなるということはありません。

これに対し、SVG アイコンを背景として配置している (CSS の background-image) 場合、ハイコントラストモードにすると IE の画面上から消えてしまいます。<img> 要素またインライン SVG でアイコンを配置している場合、 IE の画面上から消えることは無いものの、アイコン描画以外の部分が透過になっている SVG だと、ハイコントラストモードによる背景色変更に伴いアイコンの視認性が低くなる恐れがあります。

ちなみに、Mac OS X や iOS、Android のアクセシビリティ機能 (ユーザー補助機能) として用意されている色反転では、テキストだけでなく画像も併せて反転表示されるため、SVG アイコンが見えなくなったり見にくくなったりすることはありません。

テキスト (のみ) のズームに連動させるのに一手間かかる

アイコンフォントは HTML テキストの一部という扱いになるので、ブラウザでテキストのみをズームさせる操作 (IE や Mac OS X Safari、Firefox、Android Chrome などで可能です) をすると、そのままアイコンも一緒にズームされるという利点があります。たとえばリンクラベルとアイコンが一組になっているようなケースで、自然な挙動と言えます。

SVG アイコンで同様の挙動を実現するには、.svg ファイルをウェブページ上に配置する際のサイズ指定に気をつける必要があります。幸い CSS3 で「rem」という単位でのサイズ指定が可能になり、これを用いると、テキストのみのズーム操作に呼応する形で、アイコンの大きさも可変にすることができます (アイコンを CSS の background-image で配置している場合はもちろんのこと、<img> 要素で配置している場合も、CSS で width/height プロパティを rem 指定することができます)。ただ、テキストズームの有無を問わずテキストとアイコンの位置関係をきっちりコントロールするには、テキストのサイズや左右のパディングなども rem 指定で揃えておくのがよいでしょう。

...で、どうする?

こうしてみると、アイコンフォントだけでなく、SVG アイコンにも課題があることがわかります。そのうえでどうするかですが、以下のように整理できるかなと思います。

ラベルを伴うアイコンの場合
アイコンフォント、SVG アイコン、どちらでもよい。ただし、見えなくなったり見にくくなったりするリスクがあるので (アイコンフォントの場合は IE などでのフォント設定のカスタマイズによって、SVG アイコンの場合は Windows のハイコントラストモードによって)、ラベルのみで必要な情報が十分伝わるように担保する。SVG アイコンの配置は、サイズ指定を rem 単位にすることも検討する。
ラベルを伴わない (それ単体で UI 部品を形成する) アイコンの場合
アイコンフォントではなく、SVG アイコンを採用する (CSS の background-image ではなく <img> 要素で配置する)。ただし Windows のハイコントラストモードによって見にくくなるリスクを避けるために、.svg ファイルにおいてはアイコン描画以外を透過させず、アイコン描画色とのコントラストが十分な色で、背景を塗っておくのが望ましい。ユーザーの多様なズーム手段に対応するために、サイズ指定を rem 単位にすることも検討する。

いかがでしょうか。フォント設定のカスタマイズやハイコントラストモードに起因する問題は、現時点の Windows/IE の仕様に依るところが大きいので、将来的には、アイコンフォント、SVG アイコンともに、ここまで気にすることなく使えるようになればいいな...と期待しています。