CSS
JavaScript

文字間のmargin,paddingを攻略する

概要

あるサイトを構築しようとしたら、デザイナーから文字間の余白の戻しがいっぱいきて絶望したので、それに対応しようとした話
特に文字を多く扱うサイトだと参考になるかもです。

そもそも文字間について

下記のブログに詳しく書かれていますがline-heightを設定してある文字にmarginやpaddingを設定しようとすると大変です。
marginとline-heightによる"真の余白"について考える

line-heightを1に設定すれば、そこまで話は複雑じゃないのですが、line-heightが1以上に設定されている文字と文字の間に余白を作ろうとすると、line-height分、余分に余白が空いてしまいます。
逆に、line-heightを1にするクラスを付与すると、<br/>や改行した時にデザイン崩れちゃう

実際はこんな感じになります。

htmlにfont-size:15pxの状態で、
文字サイズ2remにline-heightに1.8を当てた上のh1と
文字サイズ1remにline-heightに1.8を当てたp
h1とpの間にはmargin-bottom:20pxを適用

普通.png
拡大.png

本来なら緑の縦線が20pxになるといいんだけど、実際は、オレンジの部分が20pxになってるので、line-heightの1.8分、つまり、2rem×1.8と1rem×1.8の合計12px+6pxが余分に空いてる状態。

デザイナー「38pxの余白できてるやんけ!」

これの解決に上記の記事では、calcをうまく使って解決してる
こんな感じ

cacl.png

h1のline-heightは計算してくれたけど、下のpは計算してくれてないので、結果26px空いてる図。
pのline-heightに1を設定すれば直るけど、下のpは改行あるからline-height:1にできない・・・・!!

これもうcssだけじゃ解決できないじゃん・・・・

JSを使って解決した

結果jsを使って解決しました。
こんな感じ

js.png

オレンジの部分に素でmargin-bottom:20pxを当ててます。
文字の上下のline-height分の余白を無理やり消してます。

仕組みは対象のh1やpの高さ、font-size,line-heightを計測し、実際の文字高さを計測。余分なline-height分の余白をmarginで削除するって感じです。

usage

jqeuryを読み込んだ状態で、moziクラスを付与します。
moziクラスには、以下をcssで設定してください。

.mozi{
  position: relative;
  box-sizing: content-box;
  display: block;
}

あとは下記からwww/js/characterHeight.jsをひぱってきてhead内で読み込んでください。
適用したいタグにmoziクラスを付与することで、扱えるようになります。

npmにパッケージ登録しようと思ったけど、大変だったので、また今度やります。。。

github/character_height