垂直方向に複数の段落と画像が並ぶとき、間隔を均一にしたければ、それぞれ同じ大きさのmargin
プロパティを適用するだろう。
<p><!-- ... --></p>
<p><!-- ... --></p>
<figure><!-- ... --></figure>
<p><!-- ... --></p>
:root {
--space-default: 1rlh;
}
p {
margin-block-start: var(--space-default);
margin-block-end: 0;
}
figure {
margin-block-start: var(--space-default);
margin-block-end: 0;
}
See the Pen Untitled by Yuhei Yasuda (@yuheiy) on CodePen.
しかし実際には、このようにすると段落と画像の間隔がやや詰まって見える。段落同士の間隔に比べて、段落と画像の間隔が少し狭く感じる。
これはハーフレディングが原因の現象だ。line-height
プロパティの仕様上、テキストの行の上端と下端には余白が設けられる。たとえばfont-size
プロパティが16px
で、line-height
プロパティが24px
であれば、上下に4px
の余白ができる。
(24px - 16px) / 2 = 4px
段落が連続する場合、margin
プロパティの値に加えてこのハーフレディングを加えた分の大きさの余白ができる。前の段落の下端のハーフレディングと、後の段落の上端のハーフレディングが組み合わされるため、ハーフレディングの2倍分の余白が含まれることになる。margin
プロパティが24px
で、ハーフレディングが4px
であれば、大きさは合計で32px
になる。
4px + 24px + 4px = 32px
一方、段落の直後に画像が続く場合、片方のハーフレディングしか含まれない。したがって、余白の大きさはその分小さい28px
になる。
4px + 24px = 28px
段落と画像の間隔が詰まって見えるのはこのような理由である。
この問題を解決するには、画像の周囲にハーフレディングの分を余分に含めた余白を設定するとよい。ハーフレディングの値は(1rlh - 1rem) / 2
で算出できるので、これを通常のmargin
プロパティの値と足し合わせる。
:root {
--space-rect: calc(var(--space-default) + (1rlh - 1rem) / 2);
}
figure {
margin-block-start: var(--space-rect);
margin-block-end: var(--space-rect);
}
これによって、画像の前後にも段落の間と同じ間隔が適用されるようになる。
便宜上、ここまでは画像を例に解説したが、そのほかの要素においても同様の問題が生じることがある。たとえば、背景色がついていたりボーダーで囲われていたりして、周囲との境界がはっきりしている要素。このサイトで言えば、hr
要素、pre
要素、table
要素などだ。これらについても同様にmargin
プロパティを設定する。
hr {
margin-block-start: var(--space-rect);
margin-block-end: var(--space-rect);
}
pre {
margin-block-start: var(--space-rect);
margin-block-end: var(--space-rect);
}
table {
margin-block-start: var(--space-rect);
margin-block-end: var(--space-rect);
}
ただし、これらの要素が連続して配置されると、やはりほかより狭い間隔になってしまう。--space-rect
には片方のハーフレディングの分の余白しか含まれていないが、これらの要素が連続した際にはハーフレディングの余白は存在しないため、ほかと均一にするには両方のハーフレディングの分の余白を含める必要がある。そこで、要素が連続した際にはmargin
プロパティを上書きすることで余白を均一にすることができる。
:root {
--space-rect2: calc(var(--space-default) + 1rlh - 1rem);
}
:is(hr, pre, figure, table) {
& + & {
margin-block-start: var(--space-rect2);
}
}
この記事での解説は、Hail2uのCSSで採用されている手法を参考にしたものである。