Create Columns Easily With The CSS3 Multi-Column Layout Module

Last week we looked at the css flexible box module, one of the new css tools to help with site layout. The css multi-column layout module is another that also helps with site layout and has even better support than flexible boxes.

As usual I’ve set up a demo page so you can see css3 multi-columns in action.

Screenshot from multi-column layout demo using column-width to create the columns

A quick note about browser support. Firefox, Safari, Chrome, Opera 11.1, IE 10PP all have multi-column support. As with flexible boxes we’ll need to use vendor prefixes to get everything working, but unlike flexible boxes there doesn’t appear to be any new terminology on the way.

Unfortunately it’s only the coming version of Internet Explorer that has multi-column support, however the fallback is that the visitor sees a single column, which is likely acceptable. Javascript workarounds exist for older versions of IE, which I’ll link to at the end of this post.

Creating Multi-Columns

Mutli-columns are not new as this 2005 article from A List Apart shows.

As the name implies the multi-column layout module is used to create multiple column layouts. There are 2 properties you can use to set up your multi-column layout.

  • column-count
  • column-width

The first sets exactly how many columns will display and the latter sets exactly how wide each column should be. In both cases the other will be determined by the available width.

1
2
3
4
5
<div>
  <p></p>
  <p></p>
  <p></p>
</div>

The css is simple and straightforward.

1
div {column-count: 3}

or

1
2
div {column-width: 15em}
/* You can also use absolute measurements like px */

There’s also a columns shortcut.

1
div {columns: 3 20em}

You can specify both count and width through the shortcut, but in practice you won’t use both. A pseudo-algorithm is used to calculate one based on the other and outside of some special cases only one or the other (count or width) will affect the layout.

Note that setting up the columns with column-count is more flexible as it allows the width of the columns to vary as the browser is resized.

Screenshot from multi-column layout demo using column-count to create the columns

Column Boxes

Setting a count or width creates a new container in between the content box and the content itself called the column box, though you can’t set properties on this new container. The column box has no concept of things like padding, margins, and borders.

Columns are arranged in rows. All column boxes in a row will have the same height as the other column boxes in the row, though the content in each column may not display at exactly the same height.

If you float an element inside a column box it’s floated with respect the column box and not the container around the columns. Specifying a width in % on an element inside the column box is relative to the column box and again not the container around the columns.

One last point about column boxes is each has the same stacking context within the multi-column element.

Screenshot showing multi-column gap and rule

Column Gaps and Rules

We have a little more control beyond setting up the columns. First is the ability to control the space between columns, which we do with column-gap. By default the column-gap will be equal to one ‘em’ though we can change the value of this gutter between columns.

1
div {column-gap: 2em}

In addition to the gap we can set a vertical rule between columns with the aptly named column-rule property

1
div {column-rule: thin solid #ccc}

The shortcut above can be written out in full as the 3 properties and they work similar to how borders work.

  • column-rule-width
  • column-rule-style
  • column-rule-color

Column-gaps are equal across a row of column boxes and the rule will be placed in the center of the column-gap. These gaps and rules will have the same height as the column they separate.

Column rules take up no “space’ working more like an outline than a border. They’re painted on the display just above the background. A child element inside a column box with a z-index will thus sit above column-rules. If a column contains no content a rule won’t be drawn between it and its neighboring column.

Screenshot showing subhead spanning columns

Column Fill and Column Span

You probably won’t need to use column-fill that often, if ever. It’s a way to tell the browser how much content should be in each column.

You can set values of auto (the default) or balance, which attempts to fill the columns equally. Unless you’ve constrained the columns though, both will amount to the same thing,

In playing around with the demo I’ve yet to notice any difference when changing the column-fill property, though I assume there are some cases where there is a noticeable difference.

Column-span is more useful as it allows us to have elements span multiple columns. Subheadings come to mind as an example where we may want to span columns.

1
h2 {column-span: all}

The only options are all or none so you can’t have an element span 2 out of 3 columns.

Screenshot from multi-column layout demo showing a column-break-after the heading in the leftmost column

Column Breaks

Finally there are three similar properties we can use to control how columns break around an element.

  • break-before: auto | always | avoid | left | right | page | column | avoid-page | avoid-column
  • break-inside: auto | always | avoid | left | right | page | column | avoid-page | avoid-column
  • break-after: auto | avoid | avoid-page | avoid-column

The definitions of the values above are:

  • auto — Neither force nor forbid a page/column break before (after, inside) the generated box.
  • always — Always force a page break before (after) the generated box.
  • avoid — Avoid a page/column break before (after, inside) the generated box.
  • left — Force one or two page breaks before (after) the generated box so that the next page is formatted as a left page.
  • right — Force one or two page breaks before (after) the generated box so that the next page is formatted as a right page.
  • page — Always force a page break before (after) the generated box.
  • column — Always force a column break before (after) the generated box.
  • avoid-page — Avoid a page break before (after, inside) the generated box.
  • avoid-column — Avoid a column break before (after, inside) the generated box.

The gist of all of the above is that you can force when certain content starts a new column. In practice I find myself using mainly the left and right values or leaving the breaks at the default auto.

Screenshot showing how an image would be clipped if it overflows its column

Overflow and Pagination

If an image or non-breakable word extends into a column gap it will be clipped in the middle of the gap. This is also where the column-rule would be displayed.

It’s possible to constrain columns in such a way that a multi-column element can have more columns than it has room to display.

  • Constraining column heights can lead to additional columns than the available space can show
  • Constraining the size of the page can lead to additional column boxes being moved to the next page(s).
  • Explicit column breaks can lead to additional columns being displayed outside the available space or moved to the next page(s).

Javascript Workarounds

Below are some Javascript solutions for older versions of IE. I haven’t tried any as yet, but wanted to present them in case you’d like to.

Note: Browser support for multi-columns was more limited when the video above was first presented.

Summary

Multi-columns are one of the new css layout modules we should at least begin thinking about if we’re not yet convinced to use them.

They’re very easy to work with as you can hopefully see and can be very useful in creating more complex designs for either static or flexible layouts. Play with them for a few minutes and you’ll be something of an expert.

Browser support is good, though as usual not perfect. There are Javascript workarounds for older versions of IE. Support in most other browsers goes back far enough that it’s likely not an issue.

Even without full support you may decide to use multi-columns now given the fallback is simply a single column. You might not use these columns to develop your overall layout, but you can safely use them to present content inside your layout.

Have you played with mutli-columns yet? If so what’s been your experience?

Download a free sample from my book, Design Fundamentals.

4 comments

  1. I love this layout module, and it works so well in modern browsers – EXCEPT, as you note, IE 8 and 9. It’s great IE 10 is going to support it, but without IE 8 and 9 support, looks like it’ll be a while before this is a viable global solution. In any case, I’m hoping to see this module in regular use ASAP.

    • I like it too. I wish we could use it more in practice now. On the bright side it’s not like using multi-columns breaks anything in browser that don’t support it. They get the single column, which is probably ok. Still it’ll be nice once older versions of IE fall out of use.

      I’ve been slowly digging into some of the other css modules like grids and templates and they look pretty nice too, though again not yet ready for all browsers.

  2. About column-break: it only works with -webkit (Chrome, Safari), so your demo page doesn’t work as expected in Firefox (and Opera and IE). Nice post, though; I especially like the demo page.

    • I see what you mean benny. They kind of work, but not exactly as I was intending. My powers of proofing must not have been working when I wrote this post. I was pretty sure I had gotten the demo to work cross-browser, but obviously I didn’t.

      Thanks for letting me know. Maybe I’ll take a look at the demo again and see if I can get it to work better in browsers beyond -webkit.

Leave a Reply

Your email address will not be published.

css.php