LEARNING OBJECTIVES โต
- Differentiate between modern CSS Fragmentation Level 3 properties (
break-*) and legacy CSS 2.1 properties (page-break-*). - Enforce clean page breaks before and after major document landmarks (
break-before: page,break-after: page). - Prevent ugly element slicing inside tables, cards, code blocks, and signature boxes using
break-inside: avoid. - Configure multi-page tabular data so that
<thead>and<tfoot>repeat across page transitions.
๐ The Mental Model & Story (Intuitive Foundation)
Imagine an automated printing press operating without a layout supervisor. A legal contract reaches page 3. Exactly at the bottom physical edge of the sheet, the layout engine reaches a signature block with two sign-off lines and a legally binding clause.
Without fragmentation rules, the machine slices directly through the middle of the signature box:
- The top half of the signature box and the label "I hereby agree to terms..." prints at the bottom of Page 3.
- The actual signature line and date stamp prints at the very top of Page 4.
Or consider a 5-page financial table: on pages 2, 3, 4, and 5, there are rows of bare numbers with zero column headers, leaving the reader with no idea whether column 4 represents "Net Profit" or "Tax Liability".
CSS Fragmentation is the layout supervisor. It evaluates the physical page boundaries and decides whether to allow a break, force an immediate page jump, or keep a delicate component intact on the next sheet.
DEFAULT BROKEN FRAGMENTATION PROTECTED WITH break-inside: avoid
+-----------------------------+ +-----------------------------+
| Page 1 | | Page 1 |
| Paragraph text... | | Paragraph text... |
| | | |
| +-------------------------+ | | |
| | Signature Clause Top | | | (Clean whitespace padding) |
+-+-------------------------+-+ +-----------------------------+
| Page 2 | | | Page 2 |
| | Signature Line Bottom | | | +-------------------------+ |
| +-------------------------+ | ========> | | Signature Clause Top | |
| | | | Signature Line Bottom | |
| Follow-up text... | | +-------------------------+ |
| | | |
+-----------------------------+ +-----------------------------+
(Broken sliced container) (Atomic protected component)
Technical Deep Dive & Specifications
1. Modern CSS Fragmentation vs. Legacy page-break-*
The W3C replaced the legacy CSS 2.1 page-break-* properties with the generalized CSS Fragmentation Module Level 3. Modern break-* properties control fragmentation across physical pages, multi-column columns, and multi-region regions.
| Modern Property (CSS3 Fragmentation) | Legacy Alias (CSS 2.1) | Primary Values | Purpose & Behavior |
|---|---|---|---|
break-before |
page-break-before |
auto, avoid, avoid-page, page, left, right |
Determines whether a page/column break occurs before this element. |
break-after |
page-break-after |
auto, avoid, avoid-page, page, left, right |
Determines whether a page/column break occurs after this element. |
break-inside |
page-break-inside |
auto, avoid, avoid-page, avoid-column |
Determines whether a break is permitted within the element's interior. |
[!IMPORTANT] To support 100% of PDF generators and legacy browser rendering engines, senior engineers write dual-declaration fallbacks:
.keep-together { /* Legacy fallback */ page-break-inside: avoid; /* Modern standard */ break-inside: avoid; }
2. Fragmentation Value Matrix & Semantics
auto: The default. Breaks are inserted if natural document flow overflows the page boundary.avoid/avoid-page: Prohibits breaks. If the entire element cannot fit in the remaining space of the current page, the entire element is moved to the top of the next page.page/always: Unconditionally forces a break, pushing the target to the start of a fresh page.left/verso: Forces 1 or 2 page breaks so that the element starts on an even/left page.right/recto: Forces 1 or 2 page breaks so that the element starts on an odd/right page (standard for book chapter openings).
3. Repeating Table Headers (<thead>) Across Pages
One of the most powerful features of browser print engines is the automatic repetition of table headers when a data table spans multiple physical sheets:
table {
width: 100%;
border-collapse: collapse;
}
thead {
/* Instructs print engine to repeat header on every new page fragment */
display: table-header-group;
}
tfoot {
/* Repeats footer summary at bottom of every page fragment */
display: table-footer-group;
}
tbody tr {
/* Prevents a single row's text from being split horizontally */
break-inside: avoid;
page-break-inside: avoid;
}
PAGE 1 PAGE 2 (Continued Table)
+-----------------------------------+ +-----------------------------------+
| TABLE TITLE | | TABLE (Continued) |
| +-----------+----------+--------+ | | +-----------+----------+--------+ |
| | Item Name | Quantity | Price | | | | Item Name | Quantity | Price | | <- Repeated THEAD!
| +-----------+----------+--------+ | | +-----------+----------+--------+ |
| | Server A | 4 | $4,000 | | | | Server D | 12 | $9,600 | |
| | Server B | 8 | $6,400 | | | | Server E | 1 | $1,200 | |
| | Server C | 2 | $1,800 | | | +-----------+----------+--------+ |
+-----------------------------------+ +-----------------------------------+
๐ป Interactive Code Playground
Below is a complete, runnable HTML document demonstrating multi-page section breaks, atomic cards protected from fragmentation, and multi-page repeating table headers.
Starter Code
Line-by-Line Code Breakdown
- Lines 28โ31 (
.chapter-break): Combinesbreak-before: page;andpage-break-before: always;to unconditionally force Section 2 onto a new physical sheet. - Lines 34โ37 (
.avoid-slice): Appliesbreak-inside: avoid;to cards and signature blocks, ensuring that if an element cannot fit at the bottom of the current sheet, the layout engine shifts the entire block to the next page. - Lines 40โ42 (
thead { display: table-header-group; }): Ensures that if the equipment ledger table spans across multiple pages, the browser automatically clones the header row at the top of every subsequent page fragment. - Lines 48โ51 (
tr { break-inside: avoid; }): Prevents individual table rows from having their text sliced horizontally between page margins.
Expected Browser Render Output
- On Screen: A continuous scrolling document containing Section 1, Section 2, a styled data table, and a signature block.
- In Print Preview (
Cmd/Ctrl + P):- Page 1 contains Section 1 and the SLA card.
- Page 2 begins cleanly with Section 2, the ledger table (with full headers), and the intact signature box resting comfortably without horizontal tears.
๐๏ธ Hands-On Exercise
๐ฏ The Challenge: Fix the Sliced Invoice Audit
Scenario: Your finance department prints a 4-page transaction audit report. Currently:
- Long transaction rows get chopped in half across the bottom margin.
- The "Executive Summary", "Itemized Table", and "Compliance Signatures" all bleed into each other without dedicated page starts.
- The signature block at the end gets split: the heading appears at the bottom of Page 3, while the actual sign-off line appears on Page 4.
Instructions:
- Apply
break-before: pageto all<h2>section landmarks so each section begins on a clean page. - Apply
break-inside: avoidto table rows (<tr>) and.compliance-signoff. - Configure
<thead>to repeat across all paginated table pages withdisplay: table-header-group.
๐ Starter Code Sandbox
โ ๏ธ Common Pitfalls
- Applying
break-inside: avoidto Parent Containers indiscriminately: If you putbreak-inside: avoidon a largedivthat is $14\text{ inches}$ tall, but an A4 page is only $11.7\text{ inches}$ tall, the browser cannot fit the box on any page and will be forced to clip or overflow uncontrollably. Only applybreak-inside: avoidto elements that can comfortably fit on a single page. - Using Flexbox or Grid on Multi-Page Tables: While CSS Grid is great for screens, print layout engines struggle to paginate grid containers cleanly across page breaks. Standard HTML
<table>elements with<thead>,<tbody>, and<tfoot>handle multi-page fragmentation far more reliably. - Forgetting
h1, h2, h3 { break-after: avoid; }: By default, a heading might render at the very last line of Page 1, while its corresponding body paragraph starts at the top of Page 2. Settingh1, h2, h3 { break-after: avoid; }keeps headings bound to their following text.
๐ก Pro Tips
- Use
break-after: avoidfor Heading Attachment: Prevent orphaned headings by declaring:h1, h2, h3, h4, h5, h6 { break-after: avoid; page-break-after: avoid; } - Always Pair Modern and Legacy Properties: Modern Chrome and Firefox support
break-inside: avoid, but older PDF libraries (e.g. wkhtmltopdf, older Chromium engines) rely strictly onpage-break-inside: avoid. Always declare both in production. - Force Right-Hand Page Starts for Book Chapters: In book publishing, major chapters always open on odd (right-hand / recto) pages. Use
break-before: right;(orbreak-before: recto;) so the print engine automatically inserts a blank verso page if needed.
๐ Key Takeaways
- CSS Fragmentation Level 3 (
break-before,break-after,break-inside) standardizes page and column break management. break-inside: avoidprevents cards, signature blocks, and callout containers from being sliced across page margins.- Multi-page tables repeat their header rows automatically when
thead { display: table-header-group; }is active. - Headings should always declare
break-after: avoidto prevent them from dangling at the bottom of a page without content. - Always write dual-declaration fallbacks (
page-break-*andbreak-*) for maximum cross-browser and headless PDF engine compatibility. - --