Exploring Multi-Column Layouts in CSS

Layouts where content flows between multiple columns and multi-column magazine-style layouts can now easily be implemented in CSS using a few simple rules defined as part of the CSS Multi-column Layout specification. This, along with CSS grid and flexbox, really allows us to define pretty much any kind of layout with minimum effort. Let’s go over what’s currently possible in terms of multi-column layouts.

Basic Multi-Column Layouts

Multi-column layouts are defined with either the column-count or the column-width properties set on a containing block element.

column-count

column-count takes an integer value for the number of columns that the block element should have:

.col {
  background: var(--subtle-yellow2);
  padding: 1rem 2rem;
}

.col-3 {
  column-count: 3;
}
<article class="col col-3">
  <p>...</p>
  <p>...</p>
  <p>...</p>
</article>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.

Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.

To create a responsive layout, it’s as simple as setting a different number of columns on smaller viewports:

@media (max-width: 600px) {
  .col-3 {
    column-count: 1;
  }
}
@media (min-width: 601px)  and (max-width: 900px) {
  .col-3 {
    column-count: 2;
  }
}

column-width

With column-width, instead of providing an exact number of columns, you provide a suggested width for them and the number of columns will be computed against that and the available space. Here’s an example where columns have a width of 8rem:

.col-8rem {
  column-width: 8rem;
}
<article class="col col-8rem">
  <p>...</p>
  <p>...</p>
  <p>...</p>
</article>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.

Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.

If you resize your viewport you'll notice that using column-width will make the multi-column layout responsive by default without the need to define a different number of columns for smaller viewports.

columns

There’s also a shorthand property for column-count and column-with called columns. Here’s how you would set a container to have 2 columns or columns with a width of 12rem:

.col-2-12rem {
  columns: 2 12rem;
}

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.

Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.

Setting both a column count and a column width is perhaps a bit odd for most use cases, because it's then left to the browser to decide to follow either the provided count or the width.

Gaps & Rules

You can specify the width of the gaps between columns using the column-gap property and you can define a rule (line) in the middle of the gap using the column-rule property.

column-gap

By default most browsers will use a column gap of 1rem if none is specified. Here’s an example with a 5rem column-gap:

.col-gap-5rem {
  column-gap: 5rem;
}
<article class="col col-gap-5rem col-3">
  <p>...</p>
  <p>...</p>
  <p>...</p>
</article>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.

Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.

column-rule

A rule is just a line between two columns that have content. The value for the column-rule is in the same format as values for border properties:

.col-fancy-rule {
  column-rule: 3px dotted hotpink;
}
<article class="col col-fancy-rule col-3 col-gap-5rem">
  <p>...</p>
  <p>...</p>
  <p>...</p>
</article>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.

Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.

Column Span

With the column-span property set to a value of all, you can have elements within a multi-column elements that span the full width and force a row break:

.col h3 {
  column-span: all;
  border-bottom: 2px solid var(--subtle-green1);
}
<article class="col col-fancy-rule col-3 col-gap-5rem">
  <p>...</p>

  <h3>Fancy-enough Title</h3>

  <p>...</p>

  <p>...</p>
</article>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

Fancy-enough Title

Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.

Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.

Firefox doesn't support column-span at the time of this writing.

Column Breaks

You can control how an element should break between columns with the break-before, break-inside and break-after properties and with values of avoid or avoid-column. Here’s a simple example where paragraph elements won’t break into multiple columns:

.breaks p {
  break-inside: avoid-column;
}
<article class="col col-3 breaks">
  <p>...</p>

  <h3>Fancy-enough Title</h3>

  <p>...</p>
  <p>...</p>
</article>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

Fancy-enough Title

Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.

Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.

The same example without the break-inside rule would look like this, where paragraphs can flow to multiple columns:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

Fancy-enough Title

Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.

Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.

Column Fill

column-fill controls how the content will be distributed between columns. The initial value, balance, indicates to the browser that the content should be distributed evenly between the columns.

First, here’s an example where we set a hard-coded height on the multi-column container and where the content is distributed evenly because of the initial value of balance:

<article class="col col-3 b30" style="height: 500px;">
  <p>...</p>
  <p>...</p>
  <p>...</p>
</article>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.

Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.

Now here’s the same example, but with column-fill set to auto instead:

<article class="col col-3" style="column-fill: auto; height: 500px;">
  <p>...</p>
  <p>...</p>
  <p>...</p>
</article>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec odio. Quisque volutpat mattis eros. Nullam malesuada erat ut turpis. Suspendisse urna nibh, viverra non, semper suscipit, posuere a, pede.

Donec nec justo eget felis facilisis fermentum. Aliquam porttitor mauris sit amet orci. Aenean dignissim pellentesque felis.

Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.

Browser Support

Can I Use multicolumn? Data on support for the multicolumn feature across the major browsers from caniuse.com.

  Tweet It
✖ Clear

🕵 Search Results

🔎 Searching...