Guide to Responsive-Friendly CSS Columns

Avatar of Katy DeCorah
Katy DeCorah on (Updated on )

📣 Freelancers, Developers, and Part-Time Agency Owners: Kickstart Your Own Digital Agency with UACADEMY Launch by UGURUS 📣

With CSS columns you can create a print-inspired layout with little added markup that can adapt beyond a fixed canvas. A supported browser will make calculations to wrap and balance content into tidy columns. If you’re already working with a fluid layout, the columns will reflow automatically. With the right combination of properties, CSS columns can be an interesting layout option that is responsive-friendly while degrading gracefully.

Where to declare columns

You can declare columns on any block level element. Columns can be applied to a single element or applied to multiple elements by targeting their parent.

In the image below, the left side depicts CSS column rules being applied to the second paragraph to transform just that content into columns. The right side depicts the rules being applied to a container element such as a <div></div> or <article></article> to transform the elements into a multi-column layout.

single and multi element columns

How to declare columns

There are three different ways to declare columns:

  1. Declare column-count.
  2. Declare column-width.
  3. Declare both (recommended).

Let’s explore the different ways to declare columns.

1. Declare column-count

Use column-count to declare the number of columns.

article {
  -webkit-column-count: 2;
     -moz-column-count: 2;
          column-count: 2;
}

Live Demo

See the Pen [2] CSS Columns, count-count by Katy DeCorah (@katydecorah) on CodePen.

The number of columns remains consistent even as the browser width changes as demonstrated in the gif below.

column count at narrow width

2. Declare column-width

Use column-width to declare the width of the columns.

The specified value is not an absolute value, but rather a minimum width. Given the column-width, the browser will decide how many columns of at least that width can fit in the space. The browser will also take into account the gutter, or gap between columns in this calculation (more on that later). Then the browser will expand the columns to evenly distribute to fill the width of the container.

For example, if you inspect the paragraph in the live demo below, you will find that the width of the column is actually greater than 150px, which is the set value of column-width.

article {
  -webkit-column-width: 150px;
     -moz-column-width: 150px;
          column-width: 150px;
}

Live Demo

See the Pen [3] CSS Columns by Katy DeCorah (@katydecorah) on CodePen.

Once the browser cannot fit at least two columns as wide as the column-width then no columns will appear and the layout will return to a single column layout.

The gif below demonstrates how the columns release as the browser width narrows. Unlike column-count this property is inherently responsive.

column width as the browser narrows

3. Declare both (recommended)

Use column-count and column-width together for the best control over CSS columns. You can declare each property or use the shorthand columns.

When both properties are declared, column-count is the maximum number of columns and column-width is the minimum width for those columns.

article {
  -webkit-columns: 2 200px;
     -moz-columns: 2 200px;
          columns: 2 200px;
}

/* or */

article {
  -webkit-column-count: 2;
     -moz-column-count: 2;
          column-count: 2;
  -webkit-column-width: 200px;
     -moz-column-width: 200px;
          column-width: 200px;
}

Live Demo

See the Pen [4] CSS Columns, columns by Katy DeCorah (@katydecorah) on CodePen.

The gif below demonstrates how using column-count and column-width together respond as the browser width narrows.

both properties as the browser narrows

Customizing columns

There are several properties to further customize CSS columns.

column-gap

To adjust the gutter, or the space between columns, declare column-gap.

For most browsers, the default for column-gap is 1em. You can declare a new value as long as it’s greater than or equal to 0.

article {
  -webkit-columns: 2 200px;
     -moz-columns: 2 200px;
          columns: 2 200px;
  -webkit-column-gap: 4em;
     -moz-column-gap: 4em;
          column-gap: 4em;
}

Live Demo

See the Pen [5] CSS Columns, column-gap by Katy DeCorah (@katydecorah) on CodePen.

The browser will make necessary calculations to evenly space and balance the columns despite a larger gap.

The gif below demonstrates how the browser releases the columns and drops the gap when the browser width narrow.

column-gap drops when the browser width narrows

column-rule

To add a vertical line between each column, declare column-rule.

This property is the shorthand for column-rule-width, column-rule-style, column-rule-color. The shorthand follows the same styling pattern as border.

article {
  -webkit-columns: 2 200px;
     -moz-columns: 2 200px;
          columns: 2 200px;
  -webkit-column-gap: 4em;
     -moz-column-gap: 4em;
          column-gap: 4em;
  -webkit-column-rule: 1px dotted #ddd;
     -moz-column-rule: 1px dotted #ddd;
          column-rule: 1px dotted #ddd;
}

Live Demo

See the Pen [6] CSS Columns, column-rule by Katy DeCorah (@katydecorah) on CodePen.

Like column-gap, the vertical line will exit once the browser width is too narrow as demonstrated in the gif below.

column-rule drops as browser width narrows

column-span

To break the column flow temporarily, declare column-span on a child element. Currently, Firefox does not support this feature (but you can go vote for it on Bugzilla).

The image below contains a heading that indicates the start of a new chapter in the story, but it continues with column flow.

columns without a spanning element

To break the heading out of the column flow, add column-span: all to the element. This declaration will temporarily stop the column flow to allow the element to span the columns, but will restart the columns with the next element.

h3 { 
  -webkit-column-span: all; 
          column-span: all; 
}

Live Demo

See the Pen [7] CSS Columns, column-span by Katy DeCorah (@katydecorah) on CodePen.

column-fill

To change how the content fills the columns, declare column-fill. Currently, this property is only available in Firefox.

When height is added to a columned element, Firefox behaves differently than the other browsers. Firefox will automatically balance the content, while the other browser will fill the columns sequentially.

The image below demonstrates how Firefox behaves compared to the other browsers when height is added to a columned element.

difference between auto and balance

In Firefox, you can change this behavior by declaring column-fill: auto. This rule will make the columns fill sequentially, as shown in the live demo below.

article {
  -webkit-columns: 2 200px;
     -moz-columns: 2 200px;
          columns: 2 200px;
  -moz-column-fill: auto;
       column-fill: auto;
  height: 350px;
}

Live Demo

See the Pen [8] CSS Columns, column-fill by Katy DeCorah (@katydecorah) on CodePen.

Since a height must be declared for Firefox to enable column-fill, the height constraint breaks the fluid pattern. The content expands horizontally because it cannot flow vertically as demonstrated in the gif below. In this case, a media query could be added to manage the height (more on that later).

height restriction on column-fill

The other browsers don’t support column-fill and will fill columns sequentially when a height is declared on a columned element. It’s worth noting that when height is added to any columned element, regardless of browser or use of column-fill, the constraint will break the fluid pattern.

Limitations

Columns can be an elegant way to deliver content, so long as the content remains readable. A multi-column layout can become difficult to read when the content overflows horizontally or the columns become taller than the viewport.

Content overflows horizontally

As shown in the column-fill section, if height is added to a columned element, then the element will expand horizontally to fit the content. The overflow will break the layout and send users in a different direction.

Possible Solution: create a min-width media query to declare the height rule.

In the demo below, I narrowed the browser window to find when the columns began to overflow and wrote down that number. Next, I wrote a min-width media query using the value of when the columns overflow and moved the height rule to the media query.

article {
  -webkit-columns: 2 200px;
     -moz-columns: 2 200px;
          columns: 2 200px;
  -moz-column-fill: auto;
       column-fill: auto;
}
@media (min-width: 500px) {
  article {
    height: 350px;
  }
}

Live Demo

See the Pen [11] CSS Columns, column-fill height by Katy DeCorah (@katydecorah) on CodePen.

As demonstrated in the gif below, when the columns release the height rule is out of bounds and the columns flow vertically.

height on min-width

Columns become taller than the viewport

If your column height extends beyond the viewport then users will need to scroll to follow the column flow.

Possible Solution: create a min-height media query to activate the columns.

In the example below, the columns will only activate if the columned element has a min-height: 400px;. I came to this number by shrinking the browser width to the point just before the columns release. Next, I adjusted the height of the browser to find where the columns began to fall under the viewport. I used that number for the value of the min-height media query.

@media (min-height: 400px) {
  article {
    -webkit-columns: 2 350px;
       -moz-columns: 2 350px;
            columns: 2 350px;
  }
}

Live Demo

See the Pen [10] CSS Columns, vertical friendly by Katy DeCorah (@katydecorah) on CodePen.

The gif below demonstrates that the columned element must be at least 400px tall to display the content in columns.

column on min-height only

Support

CSS columns have decent support (IE10+) and still require prefixes on all properties. Find out more details about the multi-column properties on Can I Use….

Even if your favorite browser doesn’t support multi-column layouts, keep in mind that they degrade gracefully into a single column layout. CSS columns are like the escalators of content delivery (as so eloquently put by Mitch Hedberg):

mitch hedberg

A multi-column layout cannot break, it can only become a single column layout.