文字の大きさの決定方法にはいくつかあるが、ウェブページにおいては画面の横幅を基準に行うことが多い。紙媒体での伝統を踏まえたものだ。縦横比の種類が限られ、画面の横幅から画面の大きさが推測できた時代はそれで良いが、折りたたみスマートフォンやヘッドマウンテッド・ディスプレイなども含め、多様化どころではない時代にはそぐわないように思う。どうせ横幅には制限をかけるだろうから、縦幅にどれくらい流し込むか、つまり画面に何行入るかで文字の大きさを決めたらどうだろうか。
例えば行送りが1.5の30行とすると、縦幅1080ピクセルの画面では以下のように計算できる。30という数字は手元にあった判型が特殊な横書きの本から借用する。また、1080ピクセルという数字はフルHDのディスプレイの解像度から借用する。
1080px / (1.5 * 30) = 24px
大きめの画面で大きめの文字サイズということになり、直観的には悪くなさそうな雰囲気がある。縦幅が100ピクセル増えると、文字サイズが2.222px
大きくなる計算だ。4Kディスプレイなら縦1920ピクセルなので、42.667px
になる。実際にはブラウザーのGUI領域などでもう少し小さいだろう。CSSでは描画領域の高さを*vh
単位で参照できるので、以下のように書ける。最低でもこれくらい入るという観点で決めたいので、svh
単位にしたい。
:root {
font-size: calc(100svh / (1.5 * 30));
}
このままではユーザー設定の文字サイズよりも小さくなる可能性がある。スマートフォンを横向きで使う時はそうなってしまうだろう。下限はユーザーの文字サイズ設定を尊重しなければならない。上限が難しいところだが、48px
とし、4Kディスプレイでも到達しないくらいにしておく。calc
関数をclamp
関数に変え、最小値で%
を、最大値でpx
単位を使う。
:root {
font-size: clamp(100%, 100svh / (1.5 * 30), 48px);
}
最近のスマートフォンなど、縦横比が2:1を超えるような縦長の機器では大きくなりすぎる懸念がある。縦長の機器では紙媒体と挙動が似ていると考えられるので、1行の文字数、つまり列数を固定してみたい。列数は、余白を考慮すると1行の文字数が35文字から38文字(半角英数字で70文字から75文字)くらいとなる40文字としてみる。これをmin
関数を使って、うまく切り替わるようにする。
:root {
font-size: clamp(
100%,
min(
100svh / (1.5 * 30),
100svw / 40
),
48px
);
}
これで行数と列数の両方で収まりが良いと考えられる大きさになる。描画領域に対する文章の圧(表現が難しいが、埋まり具合とか密度とか、そのような感覚のこと)が一定になるだろう。行数と列数は厳密なものではないので、それらの平均を取ってsvmin
単位を割ることでmin
関数の計算結果に近い値を出しても良いかもしれない。
:root {
font-size: clamp(
100%,
100svmin / ((1.5 * 30 + 40) / 2),
48px
);
}
テキトウに横幅に応じて大きくしていくよりは論理的だが、複雑性がかなり残る。ユーザーが設定した文字の大きさを優先しつつ、なるべく収まりの良い大きさを提供するという手法を具現化しただけなので、まだまだ手を入れるべきところはあるだろう。他の手法も考えつつ研ぎ澄ませたい。
:root {
--ratio: calc(pow(3, 2) / pow(2, 3));
--line-height-default: calc(pow(var(--ratio), 4));
--ratio-column: calc(pow(var(--ratio), 32));
font-size: max(
100%,
min(
100svh / (var(--line-height-default) * 28),
100svw / var(--ratio-column),
24px
)
);
}
手元ではこのような実装にしてみている。max
関数で100%
とその他に分けることで、ユーザー設定を優先することを明示的にする。実際の調整はmin
関数の方へ閉じ込め、マジック・ナンバーも極力使わないように気を付ける。--line-height-default
という変数を28倍にして、高さを割るなら、画面に28行収まる文字の大きさになると推察できるはずだ。また、最大サイズも24px
と控えめなものにした。タブレット端末のようなそこそこ大きい上に縦横比が正方形に近づく端末で、やや大きくなる傾向があるからだ。