安全な@font-faceの書き方

Translation of: Bulletproof @font-face syntax

最も優れた@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');
}

最後になぜこの方法が最も優れたものなのかは説明することにして、最初に他の方法の欠点を解説することにしたい。もちろん、問題の中心になるのはIEが.eotフォントが必要なのに対して、他のブラウザでは.ttfか.otfを必要とすることである。それでは順に解説していこう。

条件付コメントによる方法

<style type="text/css" media="screen">
@font-face{
  font-family:'Graublau Web';
  src: url('GraublauWeb.otf') format('opentype');
}
</style>
<!--[if IE]>
<style type="text/css" media="screen">
@font-face{
  font-family:'Graublau Web';
  src: url('GraublauWeb.eot');
}
</style>
<![endif]-->

本気なのだろうか? ありとあらゆるHTMLファイルにこのコードを挿入するか、iefont.cssというファイルを作成して参照させなくてはならない。面倒で、美しくない。

二重に定義する方法

@font-face{
  font-family:'Graublau Web';
  src: url('GraublauWeb.eot'); /* here you go, IE */
}
@font-face{
  font-family:'Graublau Web';
  src: url('GraublauWeb.otf'); /* everyone else take this */
}

Andreaが指摘したこの方法の問題点はIEが.otfファイルをダウンロードしてしまうことだ。無駄なHTTP接続が発生させることは許されない。この問題に対するよくある対処はこうなる:

@font-face {
  font-family: 'Graublau Web';
  src: url('GraublauWeb.otf') format('opentype'); /* IE no comprende format()! */
}

知っていると思うが、IEはformat()を解釈できない。ではそこで何が起こるかというと、IEは以下のようなファイルをリクエストする:

GraublauWeb.otf')%20format('opentype

これは……正規表現で?を使うの忘れたようだ。しかし、20から100 KBのファイルをダウンロードさせるよりは404の方がまだマシではある。それでは404をどうにかしてみよう:

もっと安全な方法

@font-face{
  font-family:'Graublau Web';
  src: url('GraublauWeb.eot'); /* here you go, IE */
}
@font-face{
  font-family:'Graublau Web';
  src: url(//:) format ('no404'), url('GraublauWeb.otf'); /* tricky! */
}

このエントリに対してRichard Finkが別の書き方を提示してくれたので、ここに追記しておく。その方法はurl(//:)を利用して、IEが404になるようなリクエストをさせなくするものだ。彼のエントリにはこの書き方を利用する理由を理論付けている。その主張は理解できるが、自分では利用したいとは思えない。

ローカルへの参照を利用する方法

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

かなり簡潔で明瞭だ。IE以外のブラウザは.eotファイルを飛ばし次の定義を参照する。一方、IEは二番目の定義を解釈しようとするが、local()によるファイルの場所の指定を理解できない上に、複数のファイルの場所の指定も理解できない。ということで.eotファイルを参照することになる。IEは必ず最後のsrc: url()を参照することになるので、この方法はうまく動作しないだろう

src: url(GraublauWeb.eot);
src: url(GraublauWeb.otf); /* Yeah IE will only try this one. :( */

また他の利点として、もしユーザー(訳注: サイトの訪問者)がカスタム・フォントをインストールしていた場合、ダウンロードさせないで済むことになる点が挙げられる。注意点としては、OS X上のSafariは完全なフォント名ではなくPostscriptフォント名のみを受け付けるので、両者が違う場合は両方含めて記述しなければならない:

安全な@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');
}

補足その他: