CSS組版の小技を紹介します!
『CSS組版Vivliostyle入門』のではmargin-breakプロパティについて解説しています。これは要素がページ上部に配置されたときに、上マージンを調整します。この説明自体は間違いではありませんが、1つ補足が必要です。
margin-breakプロパティのautoは、自然な流れによって要素が次ページに送られた場合は、上マージンを削除します。右ページ上の囲み枠パーツ(ティーブレイク)は上マージンが削除されていますね。
しかし、break-afterなどを使った任意改ページで送られた場合、上マージンを削除しないのです。これは組版としては不自然ですね。
この問題を解決するには、任意改ページ後に要素が続くときだけ、margin-break: discard;
を指定します。ふだん筆者はhr要素を改ページの指定に使っているので、hr + .column-d
というセレクタを追加しておけば、改ページ後の要素の上マージンを削除できます。
/* hr(改ページ)の直後のコラム */
hr + .column-d {
margin-break: discard;
}
見出しの場合、上記の方法では解決できません。VFMが見出し要素を囲むsection要素を自動生成するため、次のようなHTMLになることがあるのです。これだとhr + h4
のような簡単なセレクタでは選択できません。
<section>
<h3>h3の見出し</h3>
……中略……
<hr>
<section>
<h4>h4の見出し</h4>
……中略……
</section>
</section>
<section>
<h3>h3の見出し</h3>
……中略……
<section>
<h4>h4の見出し</h4>
……中略……
<hr>
</section>
<section>
<h4>h4の見出し</h4>
……中略……
</section>
</section>
これらのパターンも解決しようとすると、次のようなセレクタを書く必要があります。
/* hr(改ページ)の直後のh4 */
hr + h4,
hr + section > h4:first-child,
section:has(hr:last-child) + section > h4:first-child {
margin-break: discard;
}
言葉で説明すると、「hrの直後にあるsection内にある最初のh4」と「最後の要素がhrであるsectionの直後にあるsection内にある最初のh4」となります。かなりややこしいですが、これで見出しでも上マージンを削除できるようになります。
見出しの要素ごとに個別に設定するのも面倒なので、新しめの疑似クラス関数である:is()を使うと、指定をまとめられます。必要に応じて:is()のカッコ内に要素を追加してください。
hr + :is(h3, h4),
hr + section > :is(h3, h4):first-child,
section:has(hr:last-child) + section > :is(h3, h4):first-child {
margin-break: discard;
}
https://github.com/libroworks/CSSkumihan_freeformats/tree/main/blogs/margin-break