Safari 10.0 で CSS Font Loading Module Level 3 を試してみた

2016.11.07

CSS Font Loading Module Level 3

こんにちは、UI デザイナーの清田です。 Safari 10.0 から Webフォントのローディング仕様の CSS Font Loading Module Level 3 が使えるようになったよーとのことで試してみたいと思います。

Text Features

Font Loading

  • Web developers can use the CSS Font Loading Module Level 3 specification to create and load font faces from a script and track the loading status of fonts.
  • Web fonts are downloaded only if the characters of the rendered text are within the font's Unicode range.

引用 : What's New in Safari

CSS Font Loading Module Level 3 とは?

この仕様は、 CSS 内の font face に対するインタフェースを定義して,font face をスクリプトから容易に作成する/load することを可能にする。 それはまた、ページに利用されている[ 個々の font / すべての font ]の loading 状態°( “status” )を追跡するためのメソッドも提供する。

引用 : CSS Font Loading Module Level 3

なぜ読込仕様が必要なのか?

FOUT という現象をご存知でしょうか?

Flash of Unstyled Text の略称なのですが、Webフォントが指定されているサイトで、サイトをレンダリングする際に、一瞬フォントスタイルが適応されていないフォントが描画されロード完了後にWebフォントが描画される現象を指して呼ばれているとのこと。

参考サイト
- FOUT

試してみる

それでは実際にSafari 10.0 ブラウザ で CSS Font Loading Module Level 3 の動作検証を行ってみます。

Web フォントの読み込み

まずはWeb Fontを読み込むための指定をしてみたいと思います。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Safari 10.0 - CSS Font Loading Module Level 3</title>
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans" rel="stylesheet">
</head>
<body>
  <article>
    <h1>Safari 10.0 - CSS Font Loading Module Level 3</h1>
    <div id="exampleFontFace">
        CSS Font Loading Module Level 3
    </div>
  </article>
</body>
</html>

document.fonts オブジェクト

CSS Font Loading 仕様が実装されているブラウザの場合、document.fonts オブジェクト確認ができるとのこと。 試しに以下の変数をSafari 9 、Safari 10.0 のブラウザで確認してみました。

<script>

var fonts = document.fonts;
console.log(fonts)

</script>

Safari 9 の場合

ブラウザ側がまだ未対応のため、undefinedが返ってきました。

Safari 10.0 の場合

今回は、FontFaceSetが返されてきました! Safari 10.0からdocument.fontsにアクセスできることが確認できました。

document.fonts イベントハンドラーについて

Event handler Event handler event type
onloading loading
onloadingdone loadingdone
onloadingerror loadingerror

CSS Font Loading Module Level 3

上記、サイトにイベントハンドラーに関する情報が記載されていますが、残念ながらSafari 10.0では正常に動作してくれませんでした。
ちなみに、Chrome側では以下のイベントが正常に実行されました。。。

document.fonts.addEventListener('loading', function() {
    console.log("フォントの読み込み");
});
document.fonts.addEventListener('loadingerror', function() {
    console.log("フォントの読み込み失敗");
});
document.fonts.addEventListener('loadingdone', function() {
    console.log("フォントの読み込み完了");
});

document.fonts メソッドについて

document.fonts には以下のメソッドが定義されているとのこと

document.fonts.load()

指定したフォント読み込むことが可能なメソッド。読み込み完了後スタイル適応等の操作もできるみたいです。

var f = new FontFace("newfont", "url(newfont.woff)", {});
f.load.then(function (loadedFace) {
  document.fonts.add(loadedFace);
  document.body.style.fontFamily = "newfont, serif";
});

document.fonts.ready()

CSS側等で指定した外部のWebフォントが読み込みが完了後実行されるメソッド

document.fonts.ready.then(function(fontFaceSet) {
	// 引数 に document.fonts がわたされる

	// 読み込まれた時の処理を記述
	console.log("document.fonts.ready");
});

document.fonts.check()

指定したフォントが読み込まれたか判定ができるメソッド

document.fonts.ready.then(function(fontFaceSet) {

	// 指定したフォントが読み込まれたか確認
  	console.log(fontFaceSet.check("4rem Monoton")); // 戻り値は true or false
});

検証

それでは実際に、javascript側でwebフォントを読み込みとスタイル適応を行って見たいと思います。

Html

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Safari 10.0 - CSS Font Loading Module Level 3</title>
</head>
<body>
  <article>
    <h1>Safari 10.0 - CSS Font Loading Module Level 3</h1>
    <div id="exampleFontFace">
		CSS Font Loading Module Level 3
    </div>
  </article>
  <script>

    var fontFace = new FontFace(
        "Monoton",
        "url(https://fonts.gstatic.com/s/monoton/v6/au96iQ3WM1J9H5fMga5i0QLUuEpTyoUstqEm5AMlJo4.woff2)",
        {}
    );

    fontFace.load().then(function (loadedFace) {
        document.fonts.add(loadedFace);
        var element = document.getElementById("exampleFontFace");
        element.style.fontFamily = "Monoton, cursive";
        element.style.fontSize = "4rem";
    });

    document.fonts.ready.then(function(fontFaceSet) {
        // 指定したフォントが読み込まれたか確認
        console.log(fontFaceSet.check("4rem Monoton"));
    });
  </script>
</body>
</html>

実際にブラウザ表示

ブラウザ上でもWebフォントが適応された状態でレンダリングされました。

開発者ツール

読み込みの判定とフォントデータも取得できてました。

まとめ

Choremブラウザ側では既に実装されていた CSS Font Loading Module Level 3ですが、やっとSafari ブラウザ側でも対応してくれました。(まだ対応しきれていない部分もありますが、、、)。Javascript側で制御できるようになったことで、いろいろと表現の幅が広がりそうですね!

参考サイト