How to use CSS3 columns

With increasing diversity in monitor sizes, it’s not practical to design single blocks of text that take up the entire width of the screen. The traditional solution is to split text into columns manually, which is very time intensive; or to split text dynamically with JavaScript, which doesn’t function universally. Besides, this is a presentation issue, we should be able to style it with CSS without the use of grid systems or floats shouldn’t we?

CSS3 actually does provide a way for you to style your text into various columns, it even gives the ability to set a gutter — the space between those columns — this way you have full control instead of the framework or grid system setting those gaps for you.

Best of all, CSS3 degrades gracefully, so if someone’s browsing in Netscape Navigator, your site won’t break.

 

Browser Support

It’s important to note that whilst all current browsers support multi-columns in CSS3 — yes even IE10 — many recent versions — IE9 for example — do not. Even though support is good, you’ll want to include browser prefixes for webkit (-webkit-) and mozilla (-moz-). There’s no need to include -ms- or -o- for IE and Opera, as they either support the feature in full, or not at all.

 

The Properties

This CSS feature actually gives you a handful of properties to give you full control over how your content gets printed in the browser and those properties are:

  • column-count: here you specify the number of columns you want to apply to the element.
  • column-width: the width of a single column. Be aware that this value will probably be changed by the browser.
  • column-gap: the width of the gap between the columns.
  • column-rule-width: the rule part is kind of a border for your columns and in here you specify the width of that border.
  • column-rule-style: also like the border, if you need to specify the style.
  • column-rule-color: here the color of the rule.
  • column-span: the value in here will tell the browser how many columns you want an element to span, this is good for headings and works like colspan and rowspan in tables.

With all of these properties I don’t think we actually need anything else to have full control over our columns. Of course not all of these properties are necessary for the multi-column layout to work, actually only the column-count is necessary but you should always also use the column-gap to give the text a little room and not have all the columns on top of one another.

To put this into practice it only takes two lines of code:

/* This will produce a 3 column layout with a gap of 20px between each column */
.cols3 {
  column-count: 3;
  column-gap: 20px;
}

If you also wish to apply a rule to the columns, you just need to add the extra properties:

/* This will produce a 3 column layout and a gap of 20px between each column and a rule of 1px solid black */
.cols3 {
  column-count: 3;
  column-gap: 20px; 
  column-rule-width: 1px;
  column-rule-style: solid;
  column-rule-color: #000;
}

Like the more common border property you can also stack the color, style and width in the same line, like so:

.cols3 {
  column-count: 3;
  column-gap: 20px;
  column-rule: 1px solid #000;
}

If you have a heading and you want that heading to span all the columns you just to add one line:

/*This h1 will take up the space of the 3 columns*/
.cols3 h1{
  column-span: all;
}

 

Demo

You can apply this to virtually any HTML, from a single paragraph to multiple <div>s. Here’s a demo:

And here is the full code to produce that effect:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="utf-8" />
 <title>CSS3 column demo</title>
 <style type='text/css'>

 .cols3 {
  -webkit-column-count: 3;
  -webkit-column-gap: 20px;
  -webkit-column-rule: 1px solid #000;

  -moz-column-count: 3;
  -moz-column-gap: 20px;
  -moz-column-rule: 1px solid #000;

  column-count: 3;
  column-gap: 20px;
  column-rule: 1px solid #000;
 }

 .cols3 h1 {
  -webkit-column-span:all;
  -moz-column-span:all;
  column-span:all;
 }

</style>
</head>
<body>

<div class='cols3'>

<h1>Integer posuere erat a ante</h1>

<p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam quis risus eget urna mollis ornare vel eu leo. Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla sed consectetur.</p>

<p>Cras mattis consectetur purus sit amet fermentum. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Etiam porta sem malesuada magna mollis euismod. Etiam porta sem malesuada magna mollis euismod. Nullam quis risus eget urna mollis ornare vel eu leo. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>

<p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nullam quis risus eget urna mollis ornare vel eu leo. Aenean lacinia bibendum nulla sed consectetur.</p>

<p>Curabitur blandit tempus porttitor. Cras mattis consectetur purus sit amet fermentum. Aenean lacinia bibendum nulla sed consectetur. Donec id elit non mi porta gravida at eget metus. Curabitur blandit tempus porttitor.</p>

</div>
</body>
</html>

 

Conclusion

Jumping to CSS columns has a lot of advantages in my opinion, no need to make use of a lot of maths, floats or content breaking when the browser gets resized by the user. You also get to write your code in a much more semantic fashion and since they’re supported by all major browser you should consider using columns from now on.

Do you style columns with CSS3, or stick to floats and positioning? What tips do you have for handling older browsers? Let us know in the comments.

Featured image/thumbnail, columns image via Shutterstock.

  • rogue3

    When viewing in FF19, the H1 in your sample is not spanning all columns. Is that just a FF issue?

  • Goran Komar

    Agreed but don’t think this was meant for long texts. If you have a three or more sections with short descriptions this is surely a quicker and cleaner way than floating.

    On the other hand, I did use this once on a long long text which I knew nobody would read but just had to be there. By emphasising a couple of key phrases throughout the text I was able to get my point across, the whole thing looked a lot better and was really easy to set up.

  • http://www.facebook.com/robert.walsh.7568 Robert Walsh

    i know the grid system is not perfect, especially if you want to use rounded borders, but i feel it is still more user friendly than using columns.

  • web designer

    I love to use columns in design especially in website like news sites or book related sites and somtimes blogs as they can benefit from not having the user scroll for ages down a page to continue reading the content.

  • aminimalanimal

    (a note in addition to my last comment, which I cannot just edit because it’s being approved)
    Setting the height doesn’t seem to work with percentages so far, but it’ll work with ems, rems, and px.

    As far as preventing the overflow columns from continuing, I haven’t found anything in the w3 working spec that seems to help in this matter, though there is the prospect of CSS Regions aiding in the future.

  • timkg

    I’m somewhat late to the party, but apparently setting “display: inline-table” prevents content items from being split in half.

  • http://todo-management.blogspot.com andrej

    is there any workaround to make this happen in IE9? Do you use a javascript plugin?

  • Belonogast

    The missing column-span of Firefox is really annoying. Is there any reason for holding back this feature?