日本語Webフォントで文字にジャギーが発生する問題の対処法

Webサイトで日本語Webフォントを導入したとき、文字にジャギーがかかる(ギザギザになったり掠れたように見える)場合がある。 その対処法について書いていく。

背景

当ブログは前回の記事に書いた方法でWebフォントを導入したのだけど、 つい先日、特定の環境で文字にジャギーがかかっていることに気づいた。 手持ちのよく使う環境では綺麗に表示されているお陰で数日間気づかないという体たらくだったのだが、 調べてみると色々な情報がヒットしたので、割とみんな悩まされているらしい。

ただ、情報は色々出るのだがしっくりくるものがなく片っ端から試す羽目になったので、 それぞれの内容についてまとめることにした。

問題の状況

使用しているのは “M PLUS Rounded 1c” というフォント。 ジャギーが発生する環境はWindowsで、少なくともFirefox、Edge、Chromeで試した限りではブラウザ問わず同じだった。 macOSとiOSでは発生しない。

フォントのジャギー

今回書いていくのは、この “M PLUS Rounded 1c” を使用することを前提とした対応策となる。

対応策

この問題を解消すべく行った内容は以下の通り。 順に見ていくことにする。

  • フォントサイズを調整する
  • 文字を若干傾ける
  • 文字に影をつける
  • font-smoothを使用する
  • 使用するフォントを変える

フォントサイズを調整する

まずはフォントのsizeを変える方法。単純だが効果は確実に得られる。 どの程度のサイズにすれば良いかはフォントやブラウザによって異なる。

今回試した”M PLUS Rounded 1c”で、Firefox、Edge、Chromeに対応するのであれば 最低でも21pxあれば問題なく表示されることを確認した。

/* 本文のセレクタに以下のCSSを追加 */
font-size: 21px;

しかし言うまでもなく本文に使うには大きすぎるので、ブログでは使い難いサイズになってしまう。 この対処で済ますなら、そもそも使うのを見出しだけにしておいて本文には使わないというのが無難かもしれない。

文字を若干傾ける

調べると案として一番よく出てくるのがこの方法。 文字の角度を僅かに傾けて、無理矢理ぼかすことで滑らかに表示させるというもの。 以下のような感じ。

/* 本文のセレクタに以下のCSSを追加 */
transform: rotate(0.03deg);

傾けるのはごくごく僅かな角度なので、人間に認識できる範囲でもなく違和感もない。 傾ける角度は好みでもう少し大きくしても良いが、これより小さいとジャギーが残るように感じたため 0.03が最低ラインかもしれない。

文字を若干傾けた場合

とにかく、前述のCSSを適用すると確かに綺麗に表示されるようになった。 これで一見なんの問題もないように見えるのだが、微妙に問題が起こる場合がある。

以下参考サイトの情報を参考に書いていく。
日本語Webフォントでシャギーが出るのを防ぐ簡単なCSS

横スクロールバーが発生する

css@transform: rotateは単に要素を回転させるためのプロパティなので、 たとえ人間に認識できない程度であっても、指定すれば確実に要素が傾いていることになる。 これにより要素が画面から僅かにはみ出し、結果として横スクロールが発生してしまう。

例えば以下のような、body全体に指定するなどといった乱暴な指定をすると起こりやすい。

/* 横スクロールが発生する例 */
body {
  transform: rotate(0.03deg);
}

もちろん左右に十分なmarginがあればはみ出すことはなくなるし、 画面全体ではなく狭い範囲でtransformを適用すれば横スクロールは発生しないため、対処が全くできないわけではない。 しかし、将来的にデザインを変えると思わぬところで再発する可能性もあるし、 CSSの指定次第ではbodyだけに限らずどんなボックスでも同様のため、 デザインを構成する上で常に気を遣う必要が出てくる。

確かにこれである程度綺麗には見えるようになるのだけど、 望みのフォントを使用できるというメリット以上に、デザインにかけるコストのデメリットが大きくなるように感じた。

画像も微妙にボケる

1つ目の問題だけでも十分に不採用の理由になるのだが、こちらは更に直接的な実害と言えるかも。

文字そのものではなく要素を傾けるというアプローチになることで、本来傾けたくない画像まで傾いてしまい、 その結果画像が僅かにボケて表示される場合がある。

例えばこのブログ(Gatsby Starter Blog)だと、以下のような指定で「記事の本文」に限定して適用するとかで1つ目の問題は何とでもなるが、 画像は記事の本文中にあるため、この程度の単純な指定では巻き込まれてボケる。

/* 横スクロールは出ないが画像はボケる例 */
body main .blog-post p {
  transform: rotate(0.03deg);
}

これもまぁ、CSSをもう少し細かくいじくればなんとかなりそうではあるので全くのお手上げとは言わないのだけど、 経験上、そうやって無理矢理辻褄を合わせようとすること自体、1つ目と同じく将来的なコストが高いと判断した。

これら2つの理由により文字傾けによる修正は諦めた。 ただ、ジャギーの解決策としては最も有力なものだと思うし、 挙げた2つの問題も先に書いた通り絶対に対処できないという類のものでは無いため、 場合によっては積極的に採用する方法になるとは思う。

文字に影をつける

文字の周りに影をつけることでアンチエイリアスっぽくしようとする方法。 結論から言えば、デメリットは少ないのだけどあまり効果も得られない。

例えば以下のようにしてみる。

body {
  /* 抑え目に影をつける */
  text-shadow: 0 0 0.2px rgba(46, 53, 63, 0.8);
}

すると以下のように表示される。

抑え目に影をつけた場合

まぁ、ちょっと変わるかなという程度。

じゃあ、と思いlengthの部分を少し上げてみる。

body {
  /* 大きめに影をつける */
  text-shadow: 0 0 0.7px rgba(46, 53, 63, 0.8);
}

すると以下のように表示される。

大きめに影をつけた場合

ギザギザはだいぶ解消される感はあるけど、今度は文字が滲んだように見えるという別の問題が起きる。 先に挙げたcss@transform: rotateと合わせて使っているところも見かけたのだけど、 ブラウザ問わず意味を感じる程度の効果は得られなかった。

これもイマイチ。というわけでこの方法も使わない。

font-smoothを使用する

font-smoothというプロパティがあるらしい。 フォントのレンダリング時のアンチエイリアスを調整するもので、以下のように使う。

body {
  /* アンチエイリアスを調整する */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

こんなプロパティがあるならそれで万事OKやん、と思ったら、 このプロパティはCSS3の標準で定義されているわけでもなく、現在はmacOSでしか動作しないらしい。 今回アンチエイリアスの問題が起きているのはWindowsなので、指定しても効果は得られない。 第一、特定のOSだけ綺麗に表示されるようになっても意味がない。

ただ、これを指定することで大きな問題が起きるとは考えにくいし、 将来的に公式で使えるようになれば(今と定義は変わるかもしれないけれど)、 その時はこの問題の解決策としてスタンダードになるかもしれないので、とりあえず指定しても損はないと思う。

もっとも、指定することでの解決も見込めないので、この方法も見送り。

使用するフォントを変える

身も蓋もないけど、ジャギーが出るフォントは最初から使わず別のフォントを使うという方法。 本来使おうとしていたWebフォントを使うという要求は満たせないが、 これまで試してきたようなCSSで無理に調整して使うというアプローチは不要になる。

結局、色々試した結果はこれになった。 あーだこーだとフォント1つに手数をかけるよりも、手間をかけない方法を選ぶことになった。

ちなみに、代替としては“Kosugi Maru”を選ぶことにした。 “M PLUS Rounded 1c”と比べるとややスッキリした印象があるものの似た雰囲気があるフォントで、 用意されたWeightは乏しいが、Google Fontsで対応されているのでFontsourceにもあるため、前回の記事と同じ方法でスムーズに導入することができた。

Shell
npm install @fontsource/kosugi-maru

結論

“M PLUS Rounded 1c”を無理に使おうとせず”Kosugi Maru”を使えばいい。
(フォント自体はどちらも好きなので、今後修正されて自由に選べることを祈りつつ)


止まらない実行を目指すITエンジニア。

© 2020-2022, Ryz