Bulletproof @font-face: Smiley variation

CSS の @font-face ルールの「安全な」書式として Paul Irish 氏の提唱する Bulletproof @font-face syntax (邦訳: hail2u.net - Weblog - 安全な@font-faceの書き方(抄訳)) がいつの間にかアップデートされていました。“Smiley variation” と名付けられたその最新版はこうなってます:

@font-face {
  font-family:
    'Graublau Web';
  src:
    url('GraublauWeb.eot');
  src:
    local('☺'),
    url('GraublauWeb.otf') format('opentype');
}

“☺”。そう、「スマイリー・フェイス」です。はじめはなにかのジョークかと思いましたがそんなことはなく、マジでした。これを src プロパティのローカル参照部分に指定すると「より安全」というわけです。なぜか?

まず、この「スマイリー版」に至る前、「オリジナル版」の Bulletproof @font-face はこうでした:

@font-face {
  font-family:
    'Graublau Web';
  src:
    url('GraublauWeb.eot');
  src:
    local('Graublau Web Regular'),
    local('Graublau Web'),
    url('GraublauWeb.otf') format('opentype');
}

ポイントはふたつの src プロパティです。IE は Web フォントとして EOT 形式しかサポートしていませんが、そのほかのどのブラウザも EOT 形式をサポートしていません。そこで、ローカルのフォント名を参照する local() 書式を解釈できない IE の実装を利用して、ふたつの指定を分岐させているのです。つまりこの例は、「IE はサーバ上の GraublauWeb.eot を参照。それ以外のブラウザは、もしローカルに Graublau Web Regular または Graublau Web という名前のフォントがあればそれを、なければサーバの GraublauWeb.otf を参照せよ」と言っていることになります。

さて、「オリジナル版」から「スマイリー版」への修正点は、このふたつめの src プロパティのうちローカルのフォント名を参照する部分です。この書き方のどこに問題があるのかというと、ローカルのフォント名はユーザの環境に依存するので、サイト制作者の意図とは異なるフォントが読み込まれる可能性がある、という点らしいです (参考: Different Fonts Named The Same: Does This Happen Frequently? | Typophile)。つまり、サイト制作者がローカルのフォント名として Graublau Web を指定しても、もし Helvetica を Graublau Web という名前で使用している人がいれば、その環境では Helvetica で表示されてしまう、ということになります。まれなケースではありますが、その可能性は否定できないわけです。

じゃあローカル参照を省略しちゃえばよくね? となるんですが、前述のとおりそもそもこの記述は IE とそのほかのブラウザで指定を振り分けるためのものなので、local() の部分を削除すると IE 向けの指定が上書きされてしまう—つまり IE で Web フォントが無効になってしまいます。

そこで Irish 氏が提案しているのが、ローカル参照としてあえて「ありえないフォント名」を指定するという方法です。Mac では Unicode の 2 バイト文字がフォント名として無効なこともあり、“☺” という名前のフォントがローカルにインストールされている、または今後リリースされる可能性はまずないであろう、と。

この結果、IE は変わらず local() が指定された src プロパティを無視するのでサーバの EOT フォントを読み込み、そのほかのブラウザは “☺” フォントをローカルで探すものの見あたらないのでやはりサーバのフォントを読み込む、ということになります。めでたしめでたし。

なお、以前このブログでも 紹介 した Font Squirrel でダウンロードできる CSS ファイルはこの「スマイリー版」で記述されており、Irish 氏もその利用をすすめています。