Webブラウザにおける文字のアンチエイリアスの現状の最適解
こんにちは、@ln-northです。
現在は生放送のチームを担当しつつ、「このフォントなんですか」というDMに答えるBotになったりしています。
今回は、ちょっと業務でフォントレンダリングに関する問題が有り、せっかくだから、この辺に関する諸問題をきちんと解決しておこうと調べて諸々提案した所、「公開したほうが良い」と色んな人から言われたので、このブログに書き起こすことにしました。
このタイトルにするのは少し怖かったんですが、頑張って書いたので何か有りましたらぜひツッコんで頂けると幸いです。
事の発端
最近チームのデザイナーからこんなことを聞かれました。
「Safariで文字が細く見えてしまうんだけど、どうすればいい?」
確かに細く見えますね。この現象と対応について、詳しく解説していきます。
原因と問題
これは「フォントレンダリングの際のアンチエイリアス方式の問題」で、今のところMacのSafariのみで起こる現象です。
アンチエイリアスとは?
以下のようにベクター画像などをラスタライズした際に、輪郭線のジャギーを目立たないように補完する処理のことを言います。
フォントも、その中に入っているグリフはベクター画像ですので、それをディスプレイに描画する(ラスタライズ)する際に、ジャギーが目立たないようアンチエイリアスをかけています。
フォントのアンチエイリアスの方式
基本的に、グレースケール方式とサブピクセル方式の2つがあります
グレースケール方式
ジャギーの出ている箇所を、その中間色で補完する方法です。
サブピクセル方式
ディスプレイの1ドットがRGBの3ドットから構成されていることを利用し、より細かくジャギーを補完する方式です。
より細かく輪郭を補完するので、原理上、グレースケール方式より文字は太くなります 。
現在は、大体のPCの文字描画にはこの方式が使われており、スクリーンショットを撮ったときに、黒い文字の左側の輪郭が赤〜オレンジ、右側の輪郭が青っぽくなっているのはこのためです。
各OS/ブラウザの状況
ここで、各OS/ブラウザのデフォルトの方式を見てみましょう。
OS | Windows | Mac/Safari | Mac/その他のブラウザ | スマートフォン |
---|---|---|---|---|
アンチエイリアス方式 | DirectX | グレースケール | サブピクセル | グレースケール |
CSSによる制御 | 不可 | 可 | 可 | 不可(WindowsPhoneなど一部可) |
Winでは基本的にフォントレンダリングをCSSで制御することは出来ません。また、スマートフォンのブラウザもほとんど制御できず、基本的にグレースケールで表示されることが多いようでした。
MacではSafariのみがグレースケールですね、これが原因で「Safariで文字が細く見えてしまう」現象が起こっています。
デバイスのdpiによる見え方
このまま各ブラウザでアンチエイリアスを揃える設定しても良いのですが、1x, 2xの解像度による見え方を見ていきましょう。(今回はThunderbolt Display = 109ppi, MBP Retina Display = 220ppiで検証・比較。実際に表示した画面をスマホのカメラで加工が無いようにして撮りました。)
109ppi(Thunderbolt Display)
220ppi(MBP Retina Display)
以下のことがわかります
109ppi環境
- Normal/グレースケールでは、英数字は大丈夫ですが、日本語はややかすれて見えてしまうところが有ります。(font-size: 14pxでの検証)
220ppi環境
- Normal/グレースケールでも文字が見える、よりスッキリ見える
- Normal/サブピクセルとBold/グレースケールにあまり太さの変化が見られない部分があります。
例えば、SPサイトを作っていて、表示確認をRetina, Chrome(サブピクセル)などで行っていると、実機はグレースケール表示がほとんどなので、意図した表示にならないなどの問題が起こることが考えられます。(ボタンの中の文字が思ったより細く見えるなど)
以上より、理想とする状態は低解像度環境下ではサブピクセル、高解像度環境下ではグレースケールにすると、良い表示になるのではないか思います。
解決する方法
理想と思われる低解像度環境下ではサブピクセル、高解像度環境下ではグレースケールになるようにするには、解像度(CSSのpixel-ratio または resolution)によってアンチエイリアス方式を振り分けると最も良さそうです。クロスブラウザ対応も含めると、以下のCSSになります。
.hoge { /* フォントレンダリング設定: 1x解像度ではsubpixel、2x以上の解像度ではgrayscale */ -webkit-font-smoothing: subpixel-antialiased; -moz-osx-font-smoothing: unset; } @media only screen and (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) { .hoge { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } }
これでフォントレンダリングのアンチエイリアスに関する諸問題はうまく解決するかと思います。
ぜひ皆さんも、最初のreset.cssなどに組み込んでお使い下さい。
参考
CSSの指定について参考にしたページを残しておきます。
フォントスムージングの対応状況について
- http://caniuse.com/#search=font-smoothing
- サポートしているのはChrome, Safari, Opera, Firefoxのみ
- -webkit-と-moz-で全部カバーできる
- font-smoothingは標準規格にはもう無いので記述しない
CSSの解像度の振り分けについて
- https://developer.mozilla.org/ja/docs/Web/CSS/resolution
- http://caniuse.com/#feat=css-media-resolution
- IEはdppx単位に対応していないが、今回のフォントはMacのみの対応ため、dpiは設定しなくてOK
- -moz-プリフィックスもFF15以前に対するオプションなので不要
この設定の懸念として、Firefoxでは「サブピクセル/グレースケール」という指定ではなく、「既定/グレースケール」という設定しか出来ない(つまりサブピクセルは明示的に指定できない)ようです…。
この点には不安が残るが、きっとmozillaはちゃんと高解像度モニタの普及状況をみて調整してくれるでしょう!そして、そのときには、もうこのようなCSSは書かなくて済む世界になっているはず!