導入
ボタンですね。
何の変哲もないです。
だいたいこんな感じ⬇️で実装すると思います。
.button {
display: inline-grid;
place-items: center;
border-radius: 9999px;
width: min(30vw, 400px);
min-height: 44px;
background-color: darkcyan;
font-family: "Noto Sans JP", sans-serif;
color: white;
}
place-itemsで中央寄せしてるし、
テキストには色しか指定してないのに
なんか上の余白の方が広いですね。。
line-height: 1
を指定してみても結果は同じです。
なんでなんでしょうか
この記事は英語のフォントを基準にした話が多くなっています。
日本語フォントについては違う箇所もあると思うのでご了承ください。
font-sizeって何なん
Webテキストにはそれぞれ emスクエア(UPM / units per emとも呼ばれる)
という相対的なサイズの「ボックス」があるみたいです。
(もともとは金属活字において大文字「M」のプロポーションが
正方形になるように作られた基準みたいです。)
一般的にOpenTypeフォントでは1000単位、
TrueTypeフォントでは2のべき乗 1024, 2048など~に設定されます。
font-size
の指定でこのボックスの基準値を変更することで、
表示されるテキストのサイズを変えることができます。
日本語フォントは『全角』という言葉もあるように、
一般的にこのemスクエアに収まるように設計されているようです。
Webテキストにある5つのラインについて
またWebテキストには、
フォントごとに設定された5つのラインがあります。
([出典]Google Fonts -Exploring x-height & the em square: https://fonts.google.com/knowledge/choosing_type/exploring_x_height_the_em_square)
- アセンダ(Ascender) エックスハイトより上に突き出る文字の部分。b, l など
- ディセンダ(Descender) ベースラインより下に突き出る文字の部分。p, j など
- エックスハイト(x-height) 小文字xの上部から下部まで。
- ベースライン(Base line) エックスハイトの下部のライン。
- キャップハイト(Capotal Height) 大文字の上部からベースラインまで。
ボックス(emスクエア)の境界は通常、
キャップハイトの少し上、ディセンダの少し下に位置する
by Google Fonts
このラインをもとにemスクエア内にフォントが配置されますが、
上下のラインまでの距離がフォントごとに違うので
謎に上が空いていたりするんですね。。。
x-heightについて
欧文書体には大文字に対する小文字の高さ(x-height)」の比率の基準があります。
フォントごとに大文字に対しての小文字のアスペクト値が違うので
フォールバックフォントでサイズ感が変わってしまう😇ということが起きるんですね…
フォントの仮想空間を見てみる
画像は同じフォントサイズの
Noto Sans JP と ヒラギノ 角ゴ Pro を
背景色だけをつけた <span>
に入れた状態です。
何だこれは、、
全然違うじゃん、、
フォントによってこれだけx-heightにも差が出るなら
フォールバックフォントは極力使用したくなくなりますね…
フォントによって設定されている基準が違うから余白ができたりするんですね
さっきのボタンのフォントを上下の空間の差が少ない ヒラギノ 角ゴ Pro に変えたら
真ん中に見えるようになりました。
x-heightをCSSで操作
ちなみに…
x-heightによって決まる
フォントのアスペクト値は font-size-adjust
プロパティを使用して一定にすることもできます。
※Firefox, Safariでのみ使用可能です。2023.12.02現在
Can I Use: https://caniuse.com/?search=font-size-adjust
line-heightって何なん
最初の疑問は解決しましたが。。
ついでなので line-height
についても調べました。
Webに限らず、『読む』という本来の目的を考えれば
line-heightとテキストはもはやマナカナくらいニコイチの関係です。
webのline-heightの設定方法
Webでは。。
line-heightにfont-sizeより大きい値を設定すると
テキストコンテンツの上下にスペースが追加され、「1行の高さ」となります。
このスペースは leading(レディング/リーディング) と呼ばれ、
上下に半分ずつ追加されるので half-leading(ハーフレディング) とも言います。
行間とアクセシビリティ
ちなみに…
WCAGでは、達成基準の1つとして以下のように推奨されています
段落中の行送りは、少なくとも 1.5 文字分ある。そして、段落の間隔は、その行送りの少なくとも 1.5 倍以上ある
達成基準 1.4.8 視覚的提示 (https://waic.jp/translations/WCAG21/#visual-presentation)
アクセシビリティ的には
本文のline-heightは1.5欲しいということですね
行送りと行間
もともと、印刷の世界において、
レディングはテキストの ベースライン間の距離 で設定されていました。
この段落の距離のつけ方を『行送り』といいます。
なぜWebのレディングを印刷のそれに合わせなかったのかは、
Webにおけるテキストボックスの役割の多さ、
背景やボーダーをつけた時のことを考えれば必然。。。
デザインとWebのレディングの差はここから始まったんですね…
デザインツールのleadingの取り扱い
- Photoshop, Illustrator
- 従来の「行送り」の方法で設定されます。(ベースライン間の距離)
行送りについて
テキスト行のベースラインから、その上の行のベースラインまでの距離を示します。- ※ アジア言語は仮想ボディ基準で行送りされます
- XD
- line-heightと同じようにハーフレディングで行間がつきます
- 最終行にはつかないです
- ※ 文字オブジェクトの高さが実際の行の高さと異なります
- Figma
- line-heightと同じようにハーフレディングで行間がつきます
- Figmaの行間は厳密にはCSSと違い2行目以降は上にレディングが追加されるので2行目以降のテキストとの余白は調整が必要みたいです。
- 詳しくはFigmaの line-heightについての記事⬇️ に書いてあります。
テキストの余白を綺麗に実装する
なるべくデザインデータに合わせるためにはどのように実装したらいいでしょうか
ネガティブマージンなどで調整
.text {
margin-top: -0.2em;
}
ネガティブマージンなどで細かく調整する方法です。
ただフォントが変わると逆にずれてしまったりするので注意が必要です。
疑似要素で余白をつめる
1行目の行間のせいで上が揃わない…
みたいな時は疑似要素で無理やり行間を詰めることで
テキストの行間は保ったまま上下を詰めることができます。
/* mixin */
@mixin lineHeightCrop($line-height: 1.5) {
&::before {
content: "";
display: block;
margin-top: calc((1 - #{$line-height}) * 0.5em);
width: 0;
height: 0;
}
&::after {
content: "";
display: block;
margin-bottom: calc((1 - #{$line-height}) * 0.5em);
width: 0;
height: 0;
}
}
.heading {
/* ... */
line-height: 1.4;
@include lineHeightCrop(1.4);
}
text-box-trim / text-box-edge
まだ草案段階のプロパティです。
text-box-trim
はもともとは leading-trim
で提案されてました。
text-box-trim / text-box-edge プロパティを使用することで
テキストの余分な余白を消すことができるみたいです!
ボタンのテキスト中央寄せが簡単になる時代が来るかもしれないですね。。!
※現在Safari Technology Preview でのみ使用可能です。2023.12.02
Can I Use: https://caniuse.com/css-text-box-trim
まとめ
Webのテキストを理解してより綺麗なタイポグラフィを目指していきたいです
参考記事
最後に参考にした記事を載せます。見ていただいてありがとうございました🙇🏻♂️