CSS Font Loading APIでウェブフォントを読み込む

ファイルサイズが巨大で読み込みに時間のかかる日本語のウェブフォントは難しいなぁと思いつつCSS Font Loading API (CSS Font Loading Module Level 3?)も一応触ってみないとダメだよねということで最も簡単なところだけ。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
中略
  <script>
    var font = new FontFace("Noto Serif JP", "url(/font/NotoSans-Regular.otf)", {
      style: 'normal',
      weight:'400'
    });
    font.load().then(function() {
      document.fonts.add(font);
      document.getElementById('hoge').style.fontFamily = "'Noto Sans JP', sans-serif";
    });
  </script>
</head>
<body>
  <div id="hoge">ウェブフォントを適用したい部分</div>
</body>
</html>

Javascriptに慣れてれば書くまでもない基本的なことだけど、上の13行目のウェブフォント適用先の指定方法。(下2つ)

<body></body>の中すべてに適用する場合は
document.body.style.fontFamily = "'Noto Sans JP', sans-serif";

特定のクラス、例えば<div class="hoge"></div>に適用したいならdocument.getElementById('hoge').style.fontFamilyをdocument.getElementByClassName('hoge').style.fontFamilyに変えれば良いかというと、もちろんそんなわけなくて
1
2
3
4
  var hoges = document.getElementsByClassName('hoge');
  for(var i = 0; i < hoges.length; i++) {
    hoges[i].style.fontFamily = "'Noto Serif JP', sans-serif";
  }
こんな風にする。これが最適じゃないかもだけど。

または、<div class="hoge"></div>が「1つしかない」という限定条件であれば、
  document.querySelector('.hoge').style.fontFamily = "'Noto Serif JP', sans-serif";
でも、これは後々意図しない表示になる元なので勧めない。

querySelectorではなくquerySelectorAllを使えば複数にヒットさせられるけど使い方はgetElementByClassNameと殆ど変わらないかも。
1
2
3
4
  var hoges = document.querySelectorAll('.hoge');
  for(var i = 0; i < hoges.length; i++) {
    hoges[i].style.fontFamily = "'Noto Serif JP', sans-serif";
  }
こんな感じ?

ブラウザのCSS Font Loading API対応状況
Chrome, Firefoxの新しいのは対応している。SafariやOperaは周りに無いので未確認だが対応しているらしい。Microsoftのゴミはどうでもいい。気になるのはマイナーなモバイルブラウザたち。非対応だとウェブフォントが適用されないのでウェブ製作者の意図に反した表示になる。そこが難点。