Modern vs Legacy Properties
CSS originally defined page break control through three properties: page-break-before, page-break-after, and page-break-inside. These worked exclusively in paged contexts. The W3C CSS Fragmentation Module Level 3 replaced them with the unified break-before, break-after, and break-inside properties, which work across all fragmentation contexts—pages, columns, and regions.
The modern properties are a strict superset: every behaviour the legacy properties provided is available, plus additional values for column and region breaks. All major rendering engines (Chromium, WebKit) now support the modern syntax in paged contexts, and browsers treat the legacy properties as aliases.
Mapping Table: Legacy → Modern
| Legacy property | Modern equivalent | Notes |
|---|---|---|
page-break-before: auto |
break-before: auto |
Identical behaviour |
page-break-before: always |
break-before: page |
always is also accepted by modern property |
page-break-before: avoid |
break-before: avoid-page |
avoid alone avoids all break types |
page-break-before: left |
break-before: left |
Identical |
page-break-before: right |
break-before: right |
Identical |
page-break-after: auto |
break-after: auto |
Identical behaviour |
page-break-after: always |
break-after: page |
always is also accepted |
page-break-after: avoid |
break-after: avoid-page |
avoid avoids all break types |
page-break-inside: auto |
break-inside: auto |
Identical |
page-break-inside: avoid |
break-inside: avoid-page |
avoid avoids all break types |
Recommendation: Always use the modern
break-*properties. If you must support very old renderers, add the legacy property as a fallback immediately before the modern one.
break-before / break-after
break-before and break-after control whether a fragmentation break occurs before or after the principal box of an element. They accept the same set of values.
All Values
| Value | Behaviour |
|---|---|
auto |
Default. The browser may insert a break if needed, but does not force or prevent one. |
avoid |
Avoid any break (page, column, or region) before/after the element. |
always |
Force a break before/after the element in whatever fragmentation context applies. In paged media, this behaves like page. |
page |
Force a page break before/after the element. |
avoid-page |
Avoid a page break before/after the element, but allow column/region breaks. |
left |
Force one or two page breaks so the next content starts on a left-hand (even) page. Blank pages are inserted automatically. |
right |
Force one or two page breaks so the next content starts on a right-hand (odd) page. Blank pages are inserted automatically. |
recto |
Force breaks so the next content appears on the recto (front side) page. In left-to-right documents, recto is the right page. |
verso |
Force breaks so the next content appears on the verso (back side) page. In left-to-right documents, verso is the left page. |
column |
Force a column break (only meaningful in multi-column layouts). |
avoid-column |
Avoid a column break before/after the element. |
Force a New Page Before Each h2
The most common pattern in PDF generation: every major section starts on its own page.
h2 {
break-before: page;
}
This inserts a page break immediately before every <h2>. The first <h2> on the first page does not produce a leading blank page because there is no preceding content to fragment.
Start Chapters on Right-Hand Pages
For book-style documents where chapters should always begin on the right (recto) page:
.chapter {
break-before: right;
}
/* Modern alternative using recto/verso */
.chapter {
break-before: recto;
}
If the previous chapter ends on an odd page, the browser automatically inserts a blank even page so the next chapter lands on the right. The blank page can be styled with the @page :blank selector.
Inserting a Break After an Element
/* Page break after every section's last element */
.section-footer {
break-after: page;
}
/* Avoid breaking after a heading so content follows it */
h3 {
break-after: avoid;
}
The break-after: avoid on headings is critical: without it, a heading could be the last element on a page with its content starting on the next page—a poor reading experience.
break-inside
break-inside controls whether a fragmentation break is allowed within an element’s box. This is the property you use to keep content blocks together.
Values
| Value | Behaviour |
|---|---|
auto |
Default. The element may be split across pages. |
avoid |
Avoid breaking inside this element in any fragmentation context. |
avoid-page |
Avoid page breaks inside the element, but allow column breaks. |
avoid-column |
Avoid column breaks inside the element, but allow page breaks. |
Important:
break-inside: avoidis a request, not a command. If the element is taller than a page, the browser must break it—content cannot simply disappear. Design your blocks so they fit within a single page when possible.
Keep Cards and Tables Together
.card {
break-inside: avoid;
}
table {
break-inside: avoid;
}
/* If you only care about page breaks, allow column breaks */
.stat-block {
break-inside: avoid-page;
}
Prevent Images from Splitting
figure {
break-inside: avoid;
}
/* Also avoid breaking between a figure and its caption */
figure img {
break-after: avoid;
}
Wrapping an image in a <figure> and applying break-inside: avoid keeps the image and its <figcaption> together. If the figure is too tall, move it to the next page by adding break-before: auto (the default) and letting the browser handle placement.
Orphans and Widows
Orphans and widows are typographic terms inherited from print publishing. They control the minimum number of lines of a paragraph that must appear at the bottom or top of a page when a paragraph is split across pages.
orphans— The minimum number of lines of a block container that must be left at the bottom of the page before a break. An “orphan” is a lone line stranded at the end of a page.widows— The minimum number of lines of a block container that must appear at the top of the page after a break. A “widow” is a lone line stranded at the top of a new page.
Default and Recommended Values
| Property | Default value | Recommended minimum | Professional print |
|---|---|---|---|
orphans |
2 |
3 |
4 |
widows |
2 |
3 |
4 |
The default of 2 is the CSS specification’s initial value. Most style guides recommend at least 3 for readability. Professional typesetting often uses 4 or higher.
Code Examples
/* Baseline: prevent single-line orphans and widows */
p {
orphans: 3;
widows: 3;
}
/* Stricter control for professional documents */
body {
orphans: 4;
widows: 4;
}
/* Allow tighter breaks in sidebar content */
.sidebar p {
orphans: 2;
widows: 2;
}
These properties only apply to block containers that participate in an inline formatting context (essentially, elements containing lines of text). They have no effect on block-level children, tables, or flex/grid items—use break-inside for those.
Practical Patterns
Invoice: Keep Line Items Together
/* Each row should not be split across pages */
.invoice-table tr {
break-inside: avoid;
}
/* Keep the totals row attached to the table */
.invoice-totals {
break-inside: avoid;
break-before: avoid;
}
/* Prevent orphan/widow lines in notes */
.invoice-notes p {
orphans: 3;
widows: 3;
}
Report: Chapters on New Pages, Tables Intact
/* Each chapter starts on a fresh page */
.chapter {
break-before: page;
}
/* Keep headings attached to the content that follows */
h2, h3, h4 {
break-after: avoid;
}
/* Never split tables or figures */
table, figure {
break-inside: avoid;
}
/* Sensible typographic defaults */
p {
orphans: 3;
widows: 3;
}
Resume: Keep Sections Together
.resume-section {
break-inside: avoid;
}
/* Each section heading stays with its content */
.resume-section h2 {
break-after: avoid;
}
/* If a section must break, at least keep the heading
and first few items together by controlling widows */
.resume-section ul {
widows: 3;
orphans: 3;
}
/* Skills and education blocks should never split */
.skills-grid, .education-entry {
break-inside: avoid;
}
Browser Support
| Property | Chrome / Chromium | Safari / WebKit | Firefox |
|---|---|---|---|
break-before: page |
Yes | Yes | Yes |
break-after: page |
Yes | Yes | Yes |
break-inside: avoid |
Yes | Yes | Yes |
break-before: left / right |
Yes | Partial | Partial |
break-before: recto / verso |
Yes | No | No |
break-before: column |
Yes | Yes | Yes |
orphans |
Yes | Yes | No |
widows |
Yes | Yes | No |
page-break-* (legacy) |
Yes | Yes | Yes |
Chromium-based renderers (used by Doppio, Puppeteer, Playwright) have the most complete support. Firefox does not implement orphans/widows in paged media. Safari supports the core page break values but lacks recto/verso.