こなさんみんばんわ。
音楽活動の方でひとつ取り組みがありまして、そちらにリソースを割いてた分ちょっと間が空いてしまいました。その内容は後日白日の下に晒される(悪事違うわ🤣)予定ですので乞うご期待。
そんな訳で前回の記事に引き続きフォントの話となりますが、今回はヒラギノ角ゴシック (Hiragino Sans) に関する話です。font-weight
プロパティでウエイトを指定したら、同じフォントならどのブラウザでも同じウエイトで表示されるだろう…と普通は思う訳ですが、実はヒラギノ角ゴシックはそうじゃなかったという、何とも衝撃的? な話をします。あっ大丈夫、解決方法はちゃんとあります。
時間がない人のための 3 行まとめ
最初に概要と結論を書いておきます。
- macOS 環境ではブラウザによって各
font-weight
値に対応するヒラギノ角ゴシックのウエイト (W0〜W9) がバラバラ(2025 年 2 月現在) - 特に混植のようなことをしたい場合、この差が問題になることがある
- これを揃えるには
@font-face
で各ウエイトに割り当てるフォントを再定義すれば OK(CSS の具体例)
という訳で「いま忙しくて時間ないねん!」という方、ここから先は後でゆっくり読んでください。涙
前提知識: ヒラギノ角ゴシックについて(知ってる人は読み飛ばして OK)
Mac OS X の登場以降、形式やバリエーションを変えながらも Apple 製デバイスの OS にずっとバンドルされ続けてきた日本語ゴシック体フォントがヒラギノ角ゴシック1です。現在、最新の OS では W0〜W9 の 10 ウエイト2が使用できるようになっています。
画面上での表示が美しく、存在感があって読みやすいというのもありますが、何よりも Windows のメイリオと同じく OS に標準で入ってるフォントということで、Web ページのテキスト表示用として CSS の font-family
に指定されることが多いです。システムの UI フォントとしても使われてるので、Apple 製品のユーザーが一番見慣れているフォントといっていいでしょう。
ことの発端: ヒラギノ角ゴ ProN → ヒラギノ角ゴシックに変更したら何か違う
さて、この Web サイトの作成者スタイルシートはもう長いことずっと昔のままのヒラギノ角ゴ ProN 指定だったのですが、今回フォントを見直しするにあたって、これをヒラギノ角ゴシック指定に変更したんですね。
そしたらですね、Safari で見るのと Firefox で見るので、文字の太さがどうも違うんですよ。何か Firefox の方が Safari よりも細く見えます。
レンダリングの違いのような単純な話ではなさそうだし、どういうことだろうと思って開発者ツールから確認してみたところ、Firefox の方は font-weight: 400
の指定に対してヒラギノ角ゴシック W3 が使用されているのが分かりました。
font-weight: 400
に対して「使用中のフォント」欄に表示されているフォント名は Hiragino Sans W3
となっている。その名前からも分かるとおり、本来このフォントは font-weight: 300
の指定に対して割り当てられるべきものではないかと思うのですが、Firefox ではそうはなってないと。ちなみに Safari の開発者ツールではフォント名が細部まで確認できないのですが、表示の差から考えても同条件では W4 が使用されているように思えます。
font-weight
とヒラギノ角ゴシック W0〜W9 の対応を徹底調査!
とても気になったのでこうなったら徹底的に調べてやるわ! と思いまして、Google Chrome(以下 Chrome)も含めた各主要ブラウザにおいて font-weight
の値とヒラギノ角ゴシックの各ウエイトがどのように対応しているかというのをテスト用の HTML ファイルを作って調査してみました。その結果を全部まとめたのが次の表です。
Safari | Firefox | Chrome | |
---|---|---|---|
W0 | 1〜199 | 1〜199 | 1〜150 |
W1 | 200〜249 | 200〜299 | 151〜250 |
W2 | 250〜299 | 300〜399 | |
W3 | 300〜399 | 400 | 251〜350 |
W4 | 400 | 401〜500 | 351〜499, 501〜599 |
W5 | 401〜500 | 501〜600 | 500 |
W6 | 501〜600 | 601〜700 | 600〜649 |
W7 | 601〜700 | 701〜800 | 650〜749 |
W8 | 701〜800 | 801〜1000 | 750〜849 |
W9 | 801〜1000 | 850〜1000 |
font-weight
値の関係。Chrome の W4 にカンマ区切りで 2 つの範囲が示されているのは、後半 (501〜599) の範囲において W4 を疑似的に太らせたものが使用されているためである。はい、見事にバラバラな訳ですが…とりあえず、この結果に font-weight
プロパティにおける太さの代替アルゴリズムを加味して考えますと、おおよそ次のようなことが分かります。
- Firefox
font-weight: 100
を W0 として、あとは単純に900
まで100
刻みで W1 から W8 まで順に対応させている。結果font-weight: 400
が W3 となり、W9 は使用されずに余る。- Safari
font-weight: 100
が W0 なのは Firefox と同じだが、200
台を細分化して250
と W2 を対応させている。結果font-weight: 400
が W4 となり、また W9 までフルに使用している。- Chrome
- ちょっと何やってるか分からない(後述)
とりあえず Safari と Firefox のウエイトの違いについては、200
台の割り当ての違いによって 300
以降の対応がひとつずつズレているのが原因のようだ、というのは理解しました。
Chrome は太さの代替アルゴリズムを正しく実装してないのでは疑惑
ていうか Chrome のこの結果は一体何なのでしょう。先に挙げた太さの代替アルゴリズムからすると、ヒラギノ角ゴシックのように 300
, 400
, 500
それぞれに相当するウエイトを持ってるフォントで 400
相当のウエイトが使われるのは font-weight
に 400
ジャストを指定した場合しかないはずで、実際 Safari と Firefox では(ウエイトの割り当ての差はあれど)そのような実装がされていることが確認できるかと思います。
でも Chrome は 351
から 499
、さらには 501
から 599
の範囲にも(いちいち疑似的に太らせてまで)W4 を割り当てるという謎仕様です。よく分かりません。
ただ、これはヒラギノ角ゴシックだけの特殊な事情なのかもしれないとも思ったので、念のために Noto Sans CJK JP でも同じことを調べてみました。先のテスト用ファイルで「フォント」のプルダウンを「源ノ角ゴシック系(Noto Sans 含)」に変更すると、ローカルにフォント3がインストールされていれば同じことが試せます。
で、とりあえず macOS 環境での結果をまとめた4のが次の表です。Safari はシステム領域以外にインストールされたフォントを font-family
に指定しても無視される仕様なので、Firefox と Chrome のみのデータです。
Firefox | Chrome | |
---|---|---|
Thin | 1〜341 | 1〜300 |
Light | 342〜370 | |
DemiLight | 371〜399 | |
Regular | 400 | 301〜450 |
Medium | 401〜500 | 451〜500, 501〜599 |
Bold | 501〜700 | 600〜799 |
Black | 701〜1000 | 800〜1000 |
font-weight
値の関係。こちらも 501〜599 の範囲において、Chrome では Medium ウェイトを疑似的に太らせたものが使用される。こちらも似たような結果ですね。Regular が使用されるのは Firefox では 400
の時だけですが、Chrome では 301
から 450
という広範囲で使用されています。501
から 599
では(ウエイトの差はあれ)疑似的に太らせたフォントが使用されるのもヒラギノ角ゴシックの時と同様。
何となく Chrome ではあるウエイトのフォントを font-weight
のある数値に対応させたら、そこを中心に前後 50〜100 の範囲内では同じウエイトのフォントを割り当てる実装になってるように見受けられますが、まぁいずれにせよ Chrome は font-weight
の太さの代替アルゴリズムを仕様通りには実装してないように思えます。
もしこれでも正しく実装されてるのだ! と言い張るのなら、あとはもうヒラギノであれば 350
と 499
と 599
の計 3 つのウエイトに W4 を割り当ててるとしか判断のしようがないのですが、どうなんでしょうか…
もしかして Chrome はすべてのフォントをバリアブル・フォントとして扱ってるのでは疑惑
と思ってたら、さらに色々調べているうちに Safari でも似たようなウエイト範囲を示すフォントがあるのを見つけました…それが system-ui
です。正確には system-ui
を指定した際に適用されるフォント(.SF NS
とか)ですね。あっちなみにこれも先のテスト用ファイルで試せますよ。
iOS | macOS | |
---|---|---|
W0 | 1〜149 | |
W1 | 1〜249 | 150〜249 |
W2 | 250〜349 | 250〜349 |
W4 | 350〜449 | 350〜449 |
W5 | 450〜549 | 450〜649 |
W6 | 550〜749 | 650〜749 |
W7 | 750〜849 | 750〜849 |
W8 | 850〜1000 | 850〜1000 |
どうですか? 使用されるウエイトとその範囲には iOS と macOS で若干の差はありますが、Chrome と同様にあるウエイトを中心に前後 50〜100 の範囲では同じウエイトのフォントを割り当てているような感じになってますよね。
で、ここでポイントとなりそうなのが、Safari で system-ui
を指定した際に適用されるフォントの英数字部分はバリアブル・フォントであるというところ。そのバリアブル・フォントに付随する日本語フォント部分(これはバリアブルではない)が似たような挙動を示すということは、もしかすると Chrome はすべてのフォントをバリアブル・フォントであるかのように扱ってる…のかも? という気もしてきました。
分からなくもないけど、やっぱり挙動は揃えてほしいよね
これ、見た目的には確かにそのようにしておいた方が、ウエイトの極端な差はできなくなるんですよね。仕様通りだと 400
から 399
にひとつ下げただけでいきなり 300
相当のウエイトに下がってしまうので、バリアブル・フォントとそうでないフォントで混植のようなことをする場合に、フォント間でのウエイトの差が激しくなってしまいます。
そのようなことまで考えてあえてそういった実装にしているというのであれば、まぁそれは理解できなくもないのですが、でもやっぱりブラウザ間で表示に差ができてしまうというのはよろしくないと思うので、そこはちゃんと仕様通りにして他のブラウザと挙動を合わせていただきたいなーというところはありますね。ちょっと歯切れが悪くなってしまいますけど。
もしかしてその辺って仕様にきちんと定められてたりするんでしょうか? 僕がちょっと見た範囲ではそのようなものは確認できなかったのですが、もしかするとあるのかもしれない。いや、でもあるんだったら他のブラウザでも同じ実装が入ってるはずだし…まぁ一応ちょっと調べてみる、かもしれない。
以上、今日の本題ではない部分に時間を割きたくないので、この話はここまでということで。
ウエイトの違いによって起こりうる問題
余談はさておき(長い余談やな、涙)とにかくブラウザによって同じ font-weight
値に対して違うウエイトのフォントが割り当てられるというのは、普通に考えて困りますよね。ヒラギノ角ゴシック単独で使う分には気にしなければいいだけかもしれませんが、そうじゃない場合…具体的には
- 英数字と日本語部分を別のフォントに(要するに混植のようなことを)したい
- かつ英数字部分がバリアブル・フォントで細かくウエイトを制御できる
というような場合だと、せっかくあるブラウザでキレイに見えるようウエイトを揃えたのに、違うブラウザで見たら全然ウエイトが合ってなかった…ということが起こりえます。これはちょっとキツイです。
ウエイトの違いをなくすための解決策
ということでこの違いを解決したい訳ですが、これはシンプルに @font-face
アットルールを使って各ウエイトに割り当てるフォントを再定義することで、各ブラウザ間での表示を揃えることができます。具体的には以下のような CSS を用いて Safari のウエイトに合わせるようにすればいいです。
@font-face {
font-family: Hiragino Sans;
font-weight: 100;
src: local("Hiragino Sans W0");
}
@font-face {
font-family: Hiragino Sans;
font-weight: 200;
src: local("Hiragino Sans W1");
}
@font-face {
font-family: Hiragino Sans;
font-weight: 250;
src: local("Hiragino Sans W2");
}
@font-face {
font-family: Hiragino Sans;
font-weight: 300;
src: local("Hiragino Sans W3");
}
@font-face {
font-family: Hiragino Sans;
font-weight: 400;
src: local("Hiragino Sans W4");
}
@font-face {
font-family: Hiragino Sans;
font-weight: 500;
src: local("Hiragino Sans W5");
}
@font-face {
font-family: Hiragino Sans;
font-weight: 600;
src: local("Hiragino Sans W6");
}
@font-face {
font-family: Hiragino Sans;
font-weight: 700;
src: local("Hiragino Sans W7");
}
@font-face {
font-family: Hiragino Sans;
font-weight: 800;
src: local("Hiragino Sans W8");
}
@font-face {
font-family: Hiragino Sans;
font-weight: 900;
src: local("Hiragino Sans W9");
}
html { /* body でも何でも、そこは任意で */
font-family: Hiragino Sans, sans-serif;
}
@font-face
を使ってヒラギノ角ゴシックのウエイトをブラウザ間で揃える CSS コード(適用したものとしてないものを比較できるサンプル HTML ファイルで表示を確認)これで Firefox の表示はもちろん、いまいちよく分からない Chrome の謎挙動も修正され、ちゃんと W4 が font-weight: 400
にのみ対応するようになります…まぁおかげで余計に Chrome の実装が分からなくなった感じもする訳ですが、あんまり深追いはせんときます。涙
ちなみに当方で試してみた限りでは、iOS Safari(およびそのエンジンを利用する全ブラウザ)はこの定義を無視する? ようです。そのため、Firefox のウエイトに合わせるような CSS を書いても「すべての環境での表示ウエイトを合わせる」という目的は果たせません。ご注意ください。
そんな訳で
今回はフォント話の第二弾としまして、CSS でヒラギノ角ゴシックに対して同じ font-weight
値を指定しても、実際に使われるフォントはブラウザによって異なっているんやで…という話と、それでは困ることもあるので @font-face
アットルールを使って各ブラウザ間での表示を揃える方法を書いてみました。
Google Chrome の実装云々はほぼ余談なのですが、コアな方には興味深い(そしてツッコミ甲斐のある)内容ではないかと思ったので書いておきました。あとせっかくがんばってテスト用ファイル作って調べた内容を表にまでしたので、この際まとめて全部出しておきたかったという私情も割とあります😅
という訳で、一般の Web 開発者のみなさまにおかれましては、この話についてはとりあえず冒頭の 3 行まとめの部分だけを理解していただければ十分かと思っております。少しでもお役に立てましたら幸いです。
そんなことより table
の見た目はもうちょっと何とかした方がいいよな、と思いました。涙
-
旧バージョンの macOS や Mac OS X 時代にバンドルされていたのはヒラギノ角ゴ Pro(N) や Std(N) ですが、ここでは不正確なのを承知でまとめて「ヒラギノ角ゴシック」としております。ご理解・ご了承のほどを… ↩
-
iOS はデフォルトでは W3〜W8 まで、その他は追加のインストール(無料)が必要。ただしシステム領域にはインストールされないようで、Web ページの表示に使うことはできません。 ↩
-
Noto Sans CJK JP, Noto Sans JP, 源ノ角ゴシック (Source Han Sans) のいずれか。バリアブル・フォント版でも大丈夫なはずです(M2 Pro Mac mini では動作しました)が、その種類によって多少挙動が変わるようでした。 ↩
-
Windows 版の各ブラウザについては調べてないです…というかウチには Windows マシンがないので確認が取れんのですよ。誰か試してその結果をまとめて教えてください。涙 ↩