Complete CSS Course Module 12: Intermediate: CSS Components and UI Patterns

CSS Multiple Columns: column-count and column-width

  • Beginner
  • Lesson 12.5
  • 6 min read
  • 55 of 77 in the course

In short

CSS multiple columns split text into newspaper-style columns. Learn column-count, column-width, columns, column-gap, column-rule, column-span and break-inside with examples. What is a CSS multi-column layout?

CSS multiple columns split text into newspaper-style columns. Learn column-count, column-width, columns, column-gap, column-rule, column-span and break-inside with examples.

What is a CSS multi-column layout?

A multi-column layout flows content into side-by-side columns, like a newspaper or a magazine page. The text fills the first column from top to bottom, then continues at the top of the next column. You don't need extra HTML or wrapper divs for each column: the browser splits the content for you.

This is different from Flexbox and Grid. With Grid, you place each item in a column. With multi-column, the content flows through the columns like water filling one glass after another.

column-count and column-width

There are two ways to ask for columns.

  • column-count says how many columns you want.
  • column-width says how wide each column should be at least. The browser then fits as many as possible.
<article class="story">
  <h2>City Park Opens New Garden</h2>
  <p>After two years of work, the city park opened its new community garden on Saturday. More than three hundred people came to see the flower beds, the small pond and the new playground.</p>
  <p>Volunteers planted over five thousand bulbs last autumn. "We wanted a place where neighbors can meet," said one of the organizers. Children helped paint the wooden signs that show the name of each plant.</p>
  <p>The garden is open every day from sunrise to sunset. Entry is free, and on Sundays there are short tours for families and school groups.</p>
</article>
.story {
  column-count: 3;
}

The article now shows in three equal columns. The heading and paragraphs flow from the first column into the second and third.

Fixed column counts can be a problem on a phone, where three columns would be too thin to read. column-width solves this:

.story {
  column-width: 16rem;
}

Now the browser makes columns that are at least 16rem wide. On a wide screen you might get three or four columns; on a phone you get just one. It is responsive with no media query at all.

The columns shorthand sets both. columns: 16rem 3 means "columns at least 16rem wide, but never more than 3".

PropertyExampleWhat it does
column-count3This many columns (a maximum when column-width is also set)
column-width16remIdeal minimum width; the browser picks the number
columns16rem 3Shorthand for width and maximum count
column-gap2remSpace between columns (default about 1em)
column-rule1px solid #dddA line between columns, like a border
column-spanallAn element stretches across all columns
break-insideavoidDon't split this element across two columns

Tip: Prefer column-width (or columns with a width) over a bare column-count. It adapts to every screen size by itself, so you write less CSS.

Gaps, rules and spanning headings

Let's turn the story into a real newspaper layout: a gap between columns, a thin vertical line, and a headline that crosses all columns.

.story {
  columns: 15rem 3;
  column-gap: 2.5rem;
  column-rule: 1px solid #d1d5db;
  font-family: Georgia, serif;
  line-height: 1.6;
  max-width: 960px;
  margin: 0 auto;
}

.story h2 {
  column-span: all;
  margin: 0 0 1rem;
  font-size: 2rem;
  border-bottom: 3px double #111827;
}

.story p {
  margin: 0 0 1rem;
}

Now the headline runs across the top of the page, above all three columns, with a double line under it. The text below flows into three columns with wide gaps and a thin grey line in the middle of each gap. column-rule works like border: width, style and color. It takes no extra space, because it is drawn inside the gap.

Note: column-span has only two values: none (the default) and all. You can't make an element span exactly two columns. If you need that, Grid is the better tool.

Stop items breaking with break-inside: avoid

The browser can cut any element in half to balance the columns, so a box can start at the bottom of one column and end at the top of the next. For text that is fine. For a card, an image with a caption or a quote, it looks broken. break-inside: avoid tells the browser "keep this element in one piece".

<div class="tips">
  <blockquote class="quote">"Simplicity is the soul of efficiency." – Austin Freeman</blockquote>
  <figure class="photo">
    <img src="https://picsum.photos/400/250" alt="A quiet forest path">
    <figcaption>A quiet forest path in spring.</figcaption>
  </figure>
  <blockquote class="quote">"Make it work, make it right, make it fast." – Kent Beck</blockquote>
</div>
.tips {
  columns: 14rem;
  column-gap: 1.5rem;
}

.quote,
.photo {
  break-inside: avoid;
  margin: 0 0 1.5rem;
}

.photo img {
  width: 100%;
  display: block;
}

Each quote and the photo with its caption now stay together in a single column. Without break-inside: avoid, the caption could end up alone at the top of the next column, far from its picture.

Build a masonry-like card list

A masonry layout is a wall of cards with different heights that pack together with no big holes, like bricks or a Pinterest board. Multi-column gives you a simple version with almost no code.

<div class="board">
  <div class="card"><h3>Pancakes</h3><p>Fluffy breakfast pancakes with berries.</p></div>
  <div class="card"><h3>Tomato soup</h3><p>A warm, simple soup for cold evenings. Ready in thirty minutes with just six ingredients from your kitchen.</p></div>
  <div class="card"><h3>Green salad</h3><p>Fresh and quick.</p></div>
  <div class="card"><h3>Pasta bake</h3><p>Cheesy pasta baked in the oven until golden. A family favorite that also tastes great the next day.</p></div>
  <div class="card"><h3>Banana bread</h3><p>Use your old bananas for this soft, sweet loaf.</p></div>
  <div class="card"><h3>Fruit smoothie</h3><p>Blend, pour, enjoy.</p></div>
</div>
.board {
  columns: 15rem;
  column-gap: 1rem;
  padding: 1rem;
}

.card {
  break-inside: avoid;
  margin-bottom: 1rem;
  padding: 1rem;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  box-shadow: 0 2px 6px rgb(0 0 0 / 0.06);
}

.card h3 {
  margin: 0 0 0.5rem;
}

You see recipe cards of different heights stacked neatly in columns, with no empty holes between them. The space between cards comes from margin-bottom (gap only works between columns here, not between items).

Common mistake: Expecting the cards to be ordered left to right. Multi-column fills down first: cards 1 and 2 go into the first column, then 3 and 4, and so on. That is fine for a photo wall, but for a "newest first" list where order matters, use Grid instead. A true masonry mode for CSS Grid is being added to browsers, but multi-column works everywhere today.

Learn more on MDN: Multiple-column layout.

Practice exercise

Create a "Frequently used words" glossary with 12 short entries (a bold word and a one-line meaning in each). Show it in columns that are at least 12rem wide, with at most 4 columns, a dotted rule between them, and a title that spans all columns. Make sure no entry is split between two columns.

Hint: use columns: 12rem 4, column-rule: 1px dotted #9ca3af, column-span: all on the title, and break-inside: avoid on each entry.

Key takeaways

  • Multi-column layout flows content through columns like a newspaper, with no extra HTML.
  • column-count sets how many columns; column-width sets a minimum width and is responsive by itself.
  • Use column-gap for space, column-rule for a line between columns, and column-span: all for full-width headings.
  • break-inside: avoid keeps cards, figures and quotes in one piece.
  • Multi-column makes an easy masonry-like card wall, but items flow down the columns, not across.