Takumi

Pagination

Control where pages break with CSS.

Content lays out once at unbounded height. It then splits into pages. Unsplittable atoms never straddle a cut. These atoms include text lines, images, and transformed subtrees. A cut inside an atom moves to its top. This matches browser print fragmentation.

Break properties

import {  } from "takumi-pdf";

const  = await (
  <>
    < ={{ : "page" }}>Chapter two</>
    < ={{ : "avoid" }}>Keep this together.</>
  </>,
);
PropertyEffect
break-before: pageStarts the element on a new page.
break-after: pageStarts the following content on a new page.
break-inside: avoidKeeps the element on one page when it fits.
box-decoration-break: cloneRepeats borders and backgrounds on every page fragment.

A break-inside: avoid box taller than the page window cannot fit on a page. It stops participating in cut avoidance. Browsers apply the same rule.

Widows and orphans

A cut through a paragraph keeps at least orphans lines at the bottom of the page and widows lines at the top of the next. Both default to 2, like Chromium. Set them to 1 to allow lone lines:

import {  } from "takumi-pdf";

const  = await (
  < ={{ : 3, : 3 }}>
    A long report body wraps into many lines across the page boundary.
  </>,
);

Both properties inherit. When a paragraph is too short to satisfy both minimums, the orphans win, as in Chromium. A break that cannot keep the orphans moves the whole paragraph to the next page. A minimum that cannot fit the current page at all is dropped for that page, like break-inside: avoid on an oversized box.

Split decorations

A box that crosses a page break slices its border and background by default. Set box-decoration-break: clone to give each fragment complete decorations:

import {  } from "takumi-pdf";

const  = await (
  <
    ={{
      : "1px solid #d1d5db",
      : 8,
      : "clone",
    }}
  >
    Long content that continues on the next page.
  </>,
);

Last updated on

On this page