Home → Stop CSS columns from splitting an element: break-inside: avoid

Stop CSS columns from splitting an element: break-inside: avoid

By · Node.js & JavaScript developer
Published January 22, 2023 · Updated October 1, 2026

CSS multi-column layout (columns: 2) is a quick way to flow a list of cards or links into columns without a JavaScript masonry library. By default, though, the browser fills the columns like text: when a column runs out of space mid-element, the element simply continues in the next column, borders, padding and all.

The examples below were rendered in headless Chromium 153, Firefox 155 and WebKit 26.6 using the official Playwright Docker image. To detect splitting, the test counted each item's layout fragments (getClientRects().length): an item cut across two columns has two.

The problem

<div class="columns">
  <div>Item 1</div>
  <div>Item 2, which is slightly longer</div>
  <div>Item 3, which is also longer and jumps to the next column</div>
  <div>Item 4</div>
  <div>Item 5</div>
  <div>Item 6</div>
</div>
.columns {
  columns: 2;
  column-gap: 16px;
  width: 400px;
}
.columns > * {
  border: 2px solid #0ea5e9;
  border-radius: 6px;
  padding: 8px;
  margin: 0 0 8px;
}

Six items in two CSS columns; item 3 is cut in half, with its last line at the top of the second column

Item 3 starts at the bottom of the first column and finishes at the top of the second. Its bottom border is missing in column one and its top border is missing in column two. All three engines split it the same way (#3 in 2 pieces).

The fix

.columns > * {
  break-inside: avoid;
}

The same six items with break-inside: avoid; item 3 stays whole in the first column

Item 3 now stays in one piece and the columns rebalance around it. The fragment count was 1 for every item in Chromium, Firefox and WebKit. break-inside: avoid inside multi-column layout is supported in Chrome 50+, Firefox 65+ and Safari 10+ according to MDN's compatibility data, so you don't need a fallback today.

What about page-break-inside and the other tricks?

The original version of this post recommended page-break-inside: avoid. Every variant tested kept the items whole in all three engines:

none          split items: #3 in 2 pieces
avoid         split items: none     ← break-inside: avoid
legacy        split items: none     ← page-break-inside: avoid
avoid-column  split items: none     ← break-inside: avoid-column
inline-block  split items: none     ← display: inline-block; width: 100%
  • page-break-inside is the legacy property from paged media. The CSS Fragmentation spec requires browsers to alias it to break-inside, which is why it still works. Use break-inside in new code.
  • break-inside: avoid-column avoids breaks only between columns, while avoid also covers page breaks when printing. avoid is what you usually want. (avoid-column arrived later in Firefox, in version 92.)
  • display: inline-block; width: 100% is an old workaround from before browsers supported break-inside in columns. It works because inline-level boxes aren't fragmented, but it changes layout behaviour (whitespace gaps, vertical alignment, margins), so there's no reason to use it any more.

The one case it can't fix

break-inside: avoid is a request, not a guarantee. If an element is taller than a column, it has to break somewhere. With a fixed-height container (height: 160px; column-fill: auto) and an item 220 px tall:

chromium: item taller than the column, with break-inside: avoid → 2 pieces
firefox: item taller than the column, with break-inside: avoid → 2 pieces
webkit: item taller than the column, with break-inside: avoid → 2 pieces

That only happens when the container has a fixed height. With the default automatic height, the columns grow to fit the tallest unbreakable item instead. If you need items that never split and also a fixed height, multi-column layout is the wrong tool. Use CSS grid or flexbox with real rows instead.

Two related tips

  • Columns fill top to bottom, then left to right, so item 2 sits below item 1, not beside it. If the reading order should go across, use grid instead.
  • break-inside: avoid also works on elements inside a printed page (tables, figures, code blocks). Add it to your print stylesheet to keep a figure and its caption together.

Sources & further reading

About Code with Node.js

This is a personal blog and reference point of a Node.js developer.

I write and explain how different Node and JavaScript aspects work, as well as research popular and cool packages, and of course fail time to time.