Published on

The Ultimate Guide to CSS Fragmentation: Mastering `break-after`, `break-before`, and `break-inside`

Authors

'The Ultimate Guide to CSS Fragmentation: Mastering break-after, break-before, and break-inside'

Unlock the power of CSS fragmentation to control how your content breaks across pages, columns, and regions with this comprehensive guide to break-after, break-before, and break-inside.

Table of Contents

Ever had that frustrating moment? You've designed a beautiful multi-column layout or a report for printing, but a heading is stranded at the bottom of a column, its content orphaned on the next. Or a beautiful image with a caption gets sliced right in half. It's a common layout problem that can make a polished design look sloppy.

For years, developers wrestled with these issues using clever hacks or limited properties like page-break-after. But the modern web, with its sophisticated layouts and need for print-quality documents, demanded a better solution. Enter the CSS Fragmentation Module.

This specification gives us a powerful, unified set of tools to control how content breaks. At the heart of this module are three properties: break-before, break-after, and break-inside. Mastering them is the key to creating seamless, professional, and readable layouts, whether on screen or on paper.

In this guide, we'll take a deep dive into these properties. We'll explore what they are, how they work, and how you can use them with practical examples to gain precise control over your document flow.

First, What is CSS Fragmentation?

Before we jump into the properties, we need to understand the concept of fragmentation. Imagine you have a long piece of content, like this blog post. In a normal, single-column web view, it flows continuously. But if you try to print it or display it in a multi-column layout, the browser must slice that continuous flow into separate pieces. This process is called fragmentation.

Each piece is placed into a container called a fragmentainer.

  • In a multi-column layout, each column is a fragmentainer.
  • In paged media (like a print view), each page is a fragmentainer.

The break-* properties give us the power to tell the browser how and where to make these slices (or, more importantly, where not to).

The Old Way vs. The New Way: page-break-* vs. break-*

You might have seen or used the older page-break-before, page-break-after, and page-break-inside properties. These were designed specifically for paged media.

The new break-* properties are their modern successors. They are more generic and designed to work across all fragmentation contexts—not just pages, but columns and regions too. For backward compatibility, the page-break-* properties are now treated as aliases of the break-* properties.

Best Practice: Use the new break-* properties. They are the current standard and future-proof your code.


The break-before Property: Controlling Breaks Before an Element

The break-before property lets you enforce or prevent a break immediately before an element is rendered.

Use Case: Imagine you're writing a report, and you want every major section (let's say, an <h2> heading) to start at the top of a new page or column. break-before is the perfect tool for this.

Syntax and Values

.element {
  break-before: auto; /* or always, avoid, column, page, etc. */
}

Here's a breakdown of the most common values:

  • auto: The default value. The browser decides whether to insert a break or not based on its usual rules.
  • avoid: The magic word. This tells the browser to avoid a break before the element if possible. This is great for keeping a heading attached to the content that follows it.
  • always: Forces a break before the element, no matter what.
  • all: Similar to always, it forces a break, ensuring the element is the first in a new fragmentainer. It's designed to be a stronger signal than always.
  • column: Forces a column break before the element. This only applies in a multi-column context.
  • page: Forces a page break before the element. This only applies in a paged media context (like print).
  • left / right: Used in paged media for documents with facing pages (like a book). left forces one or two page breaks so the element lands on a left-hand page. right does the same for a right-hand page.
  • recto / verso: Similar to left/right but sensitive to the document's writing direction (recto is the 'front' side of a page, verso is the 'back'). In left-to-right languages, recto is the right page and verso is the left.

Practical Example 1: Starting Chapters on a New Page

Let's say you're creating a printable online book. Each chapter starts with an <h2>. You want each chapter to begin on a fresh page.

HTML:

<article class="book">
  <section class="chapter">
    <h2>Chapter 1: The Beginning</h2>
    <p>Lorem ipsum dolor sit amet...</p>
  </section>
  <section class="chapter">
    <h2>Chapter 2: The Middle</h2>
    <p>Consectetur adipiscing elit...</p>
  </section>
  <section class="chapter">
    <h2>Chapter 3: The End</h2>
    <p>Sed do eiusmod tempor incididunt...</p>
  </section>
</article>

CSS:

@media print {
  .chapter h2 {
    break-before: page; /* Or 'always' for a more general approach */
    /* For better compatibility, you might see this: */
    /* page-break-before: page; */
  }
}

When you print this document, a page break will be inserted right before every <h2> tag, giving you a clean, professional layout.

Practical Example 2: Forcing a New Column

Now, let's apply this to a multi-column layout on a webpage. Imagine a feature section where you want a specific call-to-action to always start at the top of a new column.

HTML:

<div class="features">
  <h3>Feature A</h3>
  <p>Details about feature A...</p>
  <h3>Feature B</h3>
  <p>Details about feature B...</p>
  <div class="call-to-action">
    <h4>Don't Miss Out!</h4>
    <p>This is an important message!</p>
  </div>
  <h3>Feature C</h3>
  <p>Details about feature C...</p>
</div>

CSS:

.features {
  column-count: 3;
  column-gap: 40px;
}

.call-to-action {
  break-before: column;
  /* Add some styling to make it stand out */
  background-color: #fff3cd;
  padding: 1em;
  border-radius: 8px;
}

In this layout, the "Don't Miss Out!" box will be pushed to the top of the next available column, ensuring it gets noticed.


The break-after Property: Controlling Breaks After an Element

As you might guess, break-after is the logical counterpart to break-before. It allows you to enforce or prevent a break immediately after an element.

Use Case: This is incredibly useful for ensuring that a heading isn't the last thing you see at the bottom of a page or column. You want to keep the heading and the paragraph that follows it together.

Syntax and Values

The values for break-after are identical to break-before: auto, avoid, always, all, column, page, etc.

.element {
  break-after: auto; /* or avoid, page, etc. */
}

Practical Example: Keeping Headings with Their Content

This is one of the most common and powerful uses of the break-* properties. An orphaned heading looks unprofessional. Let's fix it.

HTML:

<div class="multi-column-text">
  <p>...previous paragraph ending here.</p>
  <h2>A Very Important Section</h2>
  <p>This is the first paragraph of the important section. We must ensure the heading above is never left by itself at the bottom of a column.</p>
  <p>More content follows...</p>
</div>

CSS:

.multi-column-text {
  column-count: 2;
  column-gap: 30px;
  height: 300px; /* Set a height to force fragmentation */
}

h2 {
  break-after: avoid;
  /* For legacy support: */
  /* page-break-after: avoid; */
}

With break-after: avoid; on the <h2>, the browser will try its best to not create a column or page break between the heading and the content that follows. If the heading is near the bottom of a column, the browser will push the heading itself to the next column to keep it with its paragraph.

This small addition dramatically improves readability and flow.


The break-inside Property: Preventing Elements from Splitting

While break-before and break-after control the space around an element, break-inside controls what happens within the element itself. It's your tool to prevent an element from being split across two pages or columns.

Use Case: This is essential for elements that must be viewed as a single, cohesive unit, such as images with captions, code blocks, blockquotes, or list items.

Syntax and Values

The set of values for break-inside is simpler:

  • auto: The default. The browser is free to break inside the element if it needs to.
  • avoid: Prevents a break inside the element where possible.
  • avoid-page: Prevents a page break inside the element.
  • avoid-column: Prevents a column break inside the element.

Practical Example 1: Creating Unbreakable Figures

Nothing looks worse than an image at the bottom of one column and its caption at the top of the next. Let's make our figures atomic and unbreakable.

HTML:

<div class="article-body">
  <p>...some text here...</p>
  <figure>
    <img src="chart.png" alt="A complex chart">
    <figcaption>Fig 1. A detailed chart that must not be separated from its image.</figcaption>
  </figure>
  <p>...more text here...</p>
</div>

CSS:

.article-body {
  column-count: 2;
  height: 400px;
}

figure {
  break-inside: avoid;
  /* For legacy support: */
  /* page-break-inside: avoid; */
  
  /* Optional styling */
  border: 1px solid #ccc;
  padding: 10px;
  margin-bottom: 1em;
}

By applying break-inside: avoid; to the <figure> element, you're telling the browser: "If this entire figure can't fit in the current column, move the whole thing to the next one. Do not split it."

Practical Example 2: Unbreakable Code Blocks and List Items

This same principle applies beautifully to other types of content.

/* Prevent code blocks from being split */
pre, code {
  break-inside: avoid;
}

/* Prevent individual list items from being split */
li {
  break-inside: avoid;
}

/* You could even apply it to blockquotes */
blockquote {
  break-inside: avoid-column;
}

These simple rules add a layer of typographic polish that significantly enhances the user experience.


A Note on Widows and Orphans

The break-* properties are for controlling breaks around entire elements. But what about controlling breaks within a paragraph? That's where the widows and orphans properties come in. They are close cousins to the fragmentation properties and often used together.

  • Orphan: The first line of a paragraph left behind at the bottom of a page or column.
  • Widow: The last line of a paragraph stranded at the top of a new page or column.

Both are considered poor typography. You can control them easily in CSS:

p {
  orphans: 2; /* A paragraph must have at least 2 lines at the bottom of a column */
  widows: 2;  /* A paragraph must have at least 2 lines at the top of a new column */
}

By setting these values to 2 (or 3), you tell the browser to avoid leaving single lines isolated. The browser will adjust the break point—pushing an extra line to the next column or pulling one back—to satisfy this rule.

Combining widows, orphans, and the break-* properties gives you almost total control over your document's text flow.

Best Practices and Gotchas

As with any powerful tool, there are some best practices and potential pitfalls to keep in mind.

  1. Use avoid, Don't Overuse always: The avoid value is generally preferable to forceful breaks like always or column. avoid lets the browser make the most intelligent decision, leading to a more natural flow with less awkward whitespace. Use always or page only when a hard break is a strict requirement (e.g., chapter pages).

  2. Context is Everything: Remember, these properties do absolutely nothing in a standard, single-column, scrolling webpage. They only activate within a fragmentation context (column-count, @media print, etc.).

  3. Graceful Degradation: The good news is that browser support for these properties is quite good in modern browsers. In older browsers that don't support them, they are simply ignored. Your layout won't break; it just won't be as perfectly formatted. You can use the page-break-* aliases for better legacy support if needed.

    .unbreakable-figure {
      break-inside: avoid;
      page-break-inside: avoid; /* Fallback for older browsers */
    }
    
  4. Beware of Awkward Gaps: Overusing avoid on many elements can sometimes lead to the browser creating large empty gaps at the bottom of columns as it struggles to satisfy all your rules. Apply these properties strategically to the most important elements first.

  5. Debugging: The best way to test and debug these properties is using your browser's developer tools. For multi-column layouts, you can see the effect directly on the page. For print styles, Chrome's (and other browsers') Print Preview (Cmd/Ctrl + P) is your best friend. It gives you an instant visual representation of where your page breaks will occur.

Conclusion

The CSS Fragmentation properties—break-before, break-after, and break-inside—are the unsung heroes of advanced CSS layout. They elevate our designs from simple web pages to sophisticated, publication-quality documents.

Let's recap:

  • break-before: Controls breaks before an element. Perfect for starting new sections.
  • break-after: Controls breaks after an element. Perfect for keeping headings with their content.
  • break-inside: Controls breaks within an element. Perfect for keeping figures, lists, and code blocks whole.

By thoughtfully applying these rules, you can eliminate orphaned headings, prevent ugly splits in your content, and guide your user's eye through a clean, logical, and professional layout. So go ahead—open up your CSS and start breaking (and not breaking) with confidence!