Tuesday, September 28, 2010

An (Almost) Complete Guide to CSS3 Multi-column Layouts

One of the defining features of print design is the ubiquity of multi-column layouts. And there are a couple of good reasons why this is the case.
First of all, it’s generally easier to read lines of text between 8 and 12 words long. Second, it’s easier to control the amount of negative space in a layout with columns. For a long time, this was the primary advantage of print but CSS3 makes multi-column layouts possible online (and without the need for JavaScript).
W3C Specification: http://www.w3.org/TR/css3-multicol/

Browser Specific Support

WebKit support: Strong
Firefox support: Strong
IE9 support: None

The multi-column model

The WC3 specification introduces a number of new properties that allow us to define columns in HTML layouts. Just like print designs of old, we’re able to define the number of columns, column width, column gaps, and even rules governing overflow.
Essentially, the specification states that a multi-column element needs to have either a defined column width or column count. Browsers are supposed to render these elements similar to the way they render tables – but the content in a column layout is dynamically split into blocks.
At the moment, we’re not able to define certain properties about columns (like column-specific backgrounds), but it’s possible this might change.

The number and width of columns

column-count and column-width are the two most basic ways to define the properties of a multi-column element.

column-count

By default, column-count is set to auto. This means that if we explicitly define the column-width, the browser will sort out for itself how many columns are necessary to populate the content in the multi-column element. Obviously, that’s not always desirable so we’ll want to explicitly define the number of columns to span the content across. And it’s easy to do:
1#multicolumnElement {
2    -webkit-column-count: 2;
3    -moz-column-count: 2;
4    column-count: 2;
5}

column-width

As I mentioned, we can define column-width without defining the number of columns, and the browser will render our content dynamically (there are some fine controls available too – keep reading for those). To define column-width, we can use any of the units regularly available to CSS properties (em, px, %, etc).
1#multicolumnElement {
2    -webkit-column-width: 15em;
3    -moz-column-count: 15em;
4    column-count: 15em;
5}
Of course, we can always combine column-width and column-count:
1#multicolumnElement {
2    -webkit-column-count: 2;
3    -moz-column-count: 2;
4    column-count: 2;
5    -webkit-column-width: 15em;
6    -moz-column-width: 15em;
7    column-width: 15em;
8}

Column gaps and rules


All print designers are familiar with column widths and gaps, but web designers are addicted to the language of margins and padding.
But column gap is exactly as it sounds – the size of the space between columns defined in any unit regularly available in CSS (em, pixel, etc).

column-gap

The WC3 specification defines 1em as the default column-gap value, so we’ll use it in this example:
1#multicolumnElement {
2    -webkit-column-gap: 1em;
3    -moz-column-gap: 1em;
4    column-gap: 1em;
5}

column-rule

Column rule is another throwback to the print era. Basically, column rules are thin lines between the columns, to further aid readibility and/or to distinguish between separate stories. CSS3 gives us three different properties for the column rule: column-rule-size, column-rule-style, and column-rule-color, but we can use the shorthand column-rule to declare values for all three at once.
As you might have guessed, the regularly available units, styles, and color values can all be used:
1#multicolumnElement {
2    -webkit-column-rule: 1em solid #000;
3    -moz-column-rule: 1em solid #000;
4    column-rule: 1em solid #000;
5}

Column breaks

What if I want to break the column before an h3 tag, you ask? Well, that’s easy too. CSS3 gives us the column-break property with a number of possible related properties and values, including: auto, always, avoid, left, right, page, column, avoid-page, and avoid-column.

column-break

So if we want to break the content before every h3 tag we simply include the column-break-before property in our stylesheet:
1h2 {
2    -webkit-column-break-before:always;
3    -moz-column-break-before:always;
4    column-break-before:always;
5}

Spanning columns

If we want an element, say a headline, to span across multiple columns we can make use of the new column-span property.

column-span

column-span has two possible values: all, and regular numbers (e.g. 1,2,3). Defining column-span as all means that the given element will span across the whole multi-column block, while assigning it a regular number will limit its span to that number of columns:
01h2 {
02    -webkit-column-span:all;
03    -moz-column-span:all;
04    column-span:all;
05}
06
07h3{
08    -webkit-column-span:2;
09    -moz-column-span:2;
10    column-span:2;
11}

Filling columns

Just like print design, we might want some finer control over how columns are filled with content. CSS3 introduces column-fill to give us that kind of control.

column-fill

We can either define a value of auto or balanced. The former will sequentially fill columns with content, while the latter evenly distributes the content.
1#multicolumnElement {
2    -webkit-column-fill:auto;
3    -moz-column-fill:auto;
4    column-fill:auto;
5}

Demo!


To cap things off, I’ve created a quick demo project based on the first few paragraphs of Moby Dick. It should display correctly in both WebKit and Mozilla based browsers (though it’s not formatted properly for mobile).

http://www.kmsm.ca/2010/an-almost-complete-guide-to-css3-multi-column-layouts/

No comments: