数字の桁を揃えたくて、その行全体に等幅フォントを指定しました。その行には漢字が含まれていました。

結果、数字は揃い、漢字は私たちが選んだことのないフォントに変わっていました。

フォールバックは黙って起きる

ブラウザは1文字受け取るたびに、指定されたフォントの中を探します。なければ次のフォントへ。どれにもなければ、システムのデフォルトを使います。

この間、警告は一切出ません。コンソールのメッセージも、エラーも、赤字もありません。画面では「この行の漢字だけ、ほかと少し感じが違う」だけです。

しかもデザインカンプでは、その行はたいてい数字なので、レビューの段階では気づけません。

そこから広がる2つの落とし穴

① 等幅フォントの後ろに漢字用のフォントを並べても、そこには落ちてくれない。フォールバックは1文字ずつ起きますが、同じフォントスタックの中で、漢字は意図したフォントで止まらず、システムのデフォルトまで落ちていきます。明示的に指定しない限りは。漢字を含むラベルは、スタックに頼らず、使うフォントを直接名指しします。

② よく使われる無料のフォント配信サービスに、必要なCJK版があるとは限らない。欧文版と同じリクエストに書くと、サービスは持っているほうだけを黙って返します。リクエストは成功、ステータスコードは200、なのに半分が欠けています。

対策

等幅で囲むのは数字の部分だけにして、行全体は囲みません。

検証では、フォントのAPIに「読み込まれたか」を聞かないこと。返ってくるのは「試した」であって、「使われた」ではありません。一度キャンバスに描いて、ピクセルを比べます。違うフォントで描いた同じ文字は、必ずピクセルが違います。