Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ページ分割

sghtmltopdfはCSS Fragmentationのプロパティでページ分割を制御します。

明示的な改ページ

.chapter { break-before: page; }   /* この要素の前で改ページ */
.summary { break-after: page; }    /* この要素の後で改ページ */
.card    { break-inside: avoid; }  /* この要素をページ境界で割らない */
プロパティ受け付ける値
break-before / break-afterauto / avoid(avoid-pageavoid-columnも同義) / always(pageも同義)
break-insideauto / avoid(同上)

古いpage-break-before / page-break-after / page-break-insideもエイリアスとして受け付けます。 wkhtmltopdfやwicked_pdf向けに書いた資産をそのまま持ち込めます。

left/right/recto/verso(見開き制御)と多段組み関連の値は非対応です。

CSSを書かずに指定する

HTML属性でも書けます。

<div data-page-break="before">…</div>
<div data-page-break="after">…</div>
<div data-page-break="avoid">…</div>

こちらは弱い優先度のヒントとして扱われるので、スタイルシートのルールで個別に上書きできます。

段落が泣き別れないようにする

p {
  orphans: 3;   /* ページ末尾に最低3行は残す */
  widows: 3;    /* 次ページの先頭に最低3行は送る */
}

1以上の整数で、初期値はどちらも2です。 指定を満たせない場合は段落ごと次のページへ送られます。

@page — 用紙とページ余白

@page {
  size: A4;
  margin: 20mm;

  @top-center    { content: "請求書"; }
  @bottom-center { content: counter(page) " / " counter(pages); }
}

@page :first {
  @bottom-center { content: "表紙"; }
}
  • sizeはページサイズのキーワード(A4/Letter等)・<length>{1,2}landscape/portraitを受け付けます
  • CLIのページ設定オプションより@pageが優先されます(CLI側は初期値)
  • margin box(@top-left-corner@bottom-right-cornerの16種)にはcontentでテキストを置けます。背景色や枠線などの装飾は非対応です
  • counter(page)は現在のページ番号、counter(pages)は総ページ数です

@pageの制約

  • size/marginはページごとに変えられません。:first/:left/:right付きのsize/margin宣言はパースされますが適用されず、これらの擬似クラスは margin boxの 内容の出し分けにだけ使えます
  • 名前付きページ(@page intropage: intro)は非対応です
  • margin boxの寸法は簡略化しています。4隅は縦横マージンの交差部分で固定、残り12個は各辺を3等分した均等割りです(width指定は無視されます)
  • counter(pages)ストリーミングモードでは使えません(総ページ数が1パスでは決まらないため)

CLIの--header-centerなどのオプションは、内部的にこの@pageのmargin boxへマップされます。 両方書いた場合はCSSが勝ちます。

テーブルのページ分割

1ページに収まらないテーブルは行単位で分割され、複数ページへ流れます。

  • <thead>の行は2ページ目以降の先頭に繰り返されます。複数行の見出しにも対応し、1ページに収まる表では複製しません
  • <tfoot>はソース順に関わらずテーブル末尾へ移動しますが、各ページ下端への繰り返しは行いません(最終ページに1回だけ出ます)
  • captioncaption-sideに従って、最初(top)または最後(bottom)の断片に付きます
  • 各断片はテーブル自身の背景・枠線を引き継ぎ、border-collapse: collapseの枠線統合もページ内でそのまま効きます

既知の限界として、rowspanが分割点をまたぐセルは開始行の断片に属し、下部がページからはみ出します(クリップされません)。 行単位のbreak-inside: avoidとorphans/widows相当も未対応です。

FlexboxとGridの扱い

レイアウトページ分割
display: flexアトミック。途中で分割せず、収まらなければ次ページへ送る
display: grid行単位で分割する(複数行にまたがるアイテムがある境界では分割しない)
display: table行単位で分割する(上記)

大きなカードを並べる用途では、flexコンテナが丸ごと次ページへ飛ぶことがあります。 分割してほしい場合はGridかテーブルを使ってください。

よく使う書き方

見出しが単独でページ末尾に残らないようにする:

h2, h3 {
  break-after: avoid;   /* 見出しの直後で改ページしない */
  break-inside: avoid;
}

明細の1件が2ページに割れないようにする:

.line-item { break-inside: avoid; }

章ごとに必ず改ページする:

section.chapter + section.chapter { break-before: page; }

Note

ストリーミングモードでは:last-childなどの後方参照セレクタが常に非マッチになります。 上の例の+(隣接兄弟)は使えます。