太字にしたら急に汚くなった

見出しを太字にしたら、なぜか字が潰れて読みにくくなった。デザインツールで作ったときは綺麗だったのに、ブラウザで見ると印象が違う。こうした現象の裏にあるのが、合成ボールドと呼ばれる仕組みです。

指定されたフォントに太字のデザインが存在しない場合、多くのソフトウェアは何もしないのではなく、元の字の輪郭を機械的に太らせて太字らしきものを作り出します。同じことは斜体でも起こり、こちらは字を単純に傾けて済ませます。

本物の太字は、太くするために字の設計そのものが作り直されています。それに対して合成されたものは、細い字を無理やり膨らませただけです。当然、品質には大きな差が出ます。

この記事では、合成された書体をどう見分けるか、なぜ発生するのか、そして Web 上でどう防ぐかを整理します。

見分け方

合成されたかどうかは、拡大して次の点を確認すれば判断できます。

  1. 縦画と横画の太さの比率が変わっていない
    本来の太字は、縦線を大きく太らせ、横線はそれほど太らせません。文字の骨格を保つための設計上の工夫です。合成ボールドは輪郭を一律に膨らませるため、この比率が元のまま維持されます。全体がのっぺりと重く見えるのはこのためです。
  2. 字の内側の空間が潰れている
    「日」や「e」の中にある閉じた空間は、太くなるほど狭くなります。本物の太字では、この空間を確保するために字幅そのものを広げたり、線の配置を調整したりしています。合成の場合は外側に膨らむだけなので、内側の空間が塗り潰されて字が判別しにくくなります。
  3. 字幅がほとんど変わらないのに字間が詰まって見える
    合成ボールドは字送りの量を変えないまま輪郭だけを太らせるため、隣り合う文字の間隔が相対的に狭くなります。文章全体が窮屈になり、行が黒くべたついた印象になります。
  4. 斜体で字形が変わっていない
    欧文の本物のイタリックは、単に傾いているのではなく字形自体が別物です。合成された斜体は元の字をそのまま傾けているだけなので、この違いがそのまま判別の手がかりになります。

なぜ発生するのか

合成が起きるのは、指定した太さに対応する実際のフォントファイルが見つからないときです。原因はいくつかあります。

一つは、そもそもウェイトが一種類しかないフォントを使っている場合です。無料で配布されているフォントには、標準の太さだけが用意されているものが少なくありません。特に日本語フォントは収録する文字数が多く、ウェイトを増やすコストが高いため、太さの選択肢が限られがちです。

もう一つは、Web フォントの読み込み設定の誤りです。複数の太さを使うつもりで宣言していても、実際には一つのファイルしか読み込まれていない、あるいはすべての太さに同じファイルを割り当ててしまっている、という設定ミスは珍しくありません。この場合ブラウザは、要求された太さのファイルが実質的に存在しないと判断し、合成に切り替えます。

さらに、Web フォントの読み込みが完了する前に表示が始まり、一時的に代替フォントで描画される場面でも同じことが起こります。

@font-face の指定を見直す

Web で最も多い原因が、この宣言の書き方です。太さごとに別々の宣言を用意し、それぞれに対応するファイルと font-weight の値を正しく結び付ける必要があります。

/* 太さごとに宣言を分ける */
@font-face {
    font-family: "SampleFont";
    src: url("/static/fonts/sample-regular.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "SampleFont";
    src: url("/static/fonts/sample-bold.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

ここで両方の宣言に同じファイルを指定してしまうと、ブラウザは 700 を要求されたときに 400 のデザインを受け取り、それを太らせて表示します。見た目には太字が出ているので、問題に気付きにくいのが厄介なところです。

可変フォントを使う場合は、対応する太さの範囲をまとめて宣言します。

@font-face {
    font-family: "SampleVariable";
    src: url("/static/fonts/sample-variable.woff2") format("woff2-variations");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

CSS で合成そのものを禁止する

設定ミスを早期に見つけたい場合や、意図しない合成を確実に避けたい場合には、合成を明示的に禁止できます。

.no-synthesis {
    font-synthesis: none;
}

/* 太字の合成だけを禁止し、斜体は許可する */
.weight-only {
    font-synthesis-weight: none;
    font-synthesis-style: auto;
}

font-synthesis は太さ、斜体、スモールキャップスの合成を許可するかどうかを制御するプロパティで、個別に指定できる長い形式も用意されています。none を指定すると、対応するフォントが存在しない場合には合成せず、そのままの字形で表示されます。

開発中にこれを有効にしておくと、太字を指定したのに太くならない箇所がそのまま設定ミスの発見につながります。

禁止すればよいとは限らない

ただし、本番環境で一律に禁止するのは慎重に判断すべきです。合成を止めると、太字が用意されていない環境では強調がまったく表示されなくなります。文章の構造を太さで表現している場合、読み手に情報が伝わらなくなるという副作用が生じます。

特に、利用者の環境にインストールされたフォントを使う指定では、どのフォントで表示されるかを完全には制御できません。この場合、多少品質が落ちても強調が伝わるほうが望ましい、という判断もあり得ます。

禁止するのは、フォントを自分で配信していて、必要な太さがすべて揃っていることを保証できる場合に限るのが安全です。

まとめ

合成ボールドは、太字が存在しないフォントに対してソフトウェアが輪郭を膨らませて作る代用品です。縦横の太さ比が崩れず、字の内側が潰れ、字間が窮屈になるという特徴から見分けられます。
Web で発生する原因のほとんどは、@font-face の宣言で太さとファイルの対応を誤っていることです。まずはそこを確認し、可変フォントが使えるなら太さの範囲をまとめて宣言するのが確実です。
font-synthesis による禁止は、設定ミスを検出する手段として開発中に使うと効果的です。本番で使う場合は、強調が消えても問題ないかどうかを確認したうえで判断してください。