この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
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側で制御できるようになったことで、いろいろと表現の幅が広がりそうですね!