CSS Columns

In this post, I will walk through the new columns specification that arrived in CSS 3. I will show you the current implementation state of columns in the four major rendering engines: Gecko (Firefox), Webkit (Safari & Chrome), Trident (Internet Explorer), and Presto (Opera).

Before we get on to platform-specific issues and workarounds, though, we’ll look at the various CSS properties available for working with columns.

For more in-depth information on columns, you should check out the W3C working draft and Mozilla’s MDC page on columns. The Webkit blog also has an article, but it’s not particularly informative.

Contents

I will add more to this entry as I discover more about columns — the goal is to make it an easy-to-understand reference.

Browser capabilities

Property Gecko Webkit Trident Presto
column-count -moz-column-count -webkit-column-count
column-width -moz-column-width -webkit-column-width
columns -webkit-columns
column-gap -moz-column-gap -webkit-column-gap
column-rule-color -moz-column-rule-color -webkit-column-rule-color
column-rule-style -moz-column-rule-style -webkit-column-rule-style
column-rule-width -moz-column-rule-width -webkit-column-rule-width
column-rule -moz-column-rule column-rule
column-span
column-fill
break-before
break-inside

Browsers used for testing: Firefox 3.5.4 (Windows), Safari 4.0.2 (Windows), Internet Explorer 8.0.6001, Opera 10.00 (Windows)

Please let me know if this table is inaccurate, and I will update it.

Browser bugs

These are the bugs that I have encountered using CSS columns — if you know of more, please let me know, and I’ll add them to these lists.

Gecko bugs

  • Specifying an “overflow” (or “overflow-x” or “overflow-y”) property on an element with columns prevents the column rule from being rendered at all.
  • Column rules occasionally don’t render, regardless of the “overflow” property.
  • There is no way to break columns.

Webkit bugs

  • Pixel creep: Pixels from a later column can creep back to the bottom of the previous column. This can happen with plain text, but it is much more noticeable when you use a non-layout altering effect like text-shadow or box-shadow.
  • Text that overflows the column horizontally is chopped off
  • There is no way to break columns.

Properties

column-count

Value: | auto
Initial value: auto

If you don’t set the column-width property, column-count specifies the number of columns into which the content should be flowed.

If you specify column-width, column-count imposes a limit on the maximum number of columns to be rendered if you supply a numeric value.

column-width

Value: | auto
Initial value: auto

This property indicates the optimal column width — columns may be rendered narrower or wider by the UA, according to the available space.

If column-width has the value “auto”, then the width of the columns is determined by other means (for example, column-count).

columns

Value: column-width && column-count

The columns property is a short-hand property, used to set both column-width and column-count simultaneously.

column-gap

Value: | normal
Initial value: normal

Use column-gap to specify the size of the gutter that lies between columns. Most UAs will render “normal” as 1em.

column-rule-color

Value:

When a column-rule is specified, you may use column-rule-color to set the colour for the line drawn between columns. This property is approximately equivalent to the various border-(?)-color properties.

column-rule-style

Value:

By using column-rule-style, you may determine how the line between columns is to be rendered, if at all. Similar to border-(?)-style.

column-rule-width

Value:
Initial value: medium

column-rule-width sets the width of the line rendered in the gutter between columns. Basically, it’s the same as the border-(?)-width properties.

column-rule

Value: column-rule-width && column-rule-style & & column-rule-color

Shorthand for setting all three column-rule properties.

column-span

Value: 1 | all
Initial value: 1

By using column-span, you can allow an element to span either the entire set of columns, or none at all.

Note that you cannot set an arbitrary number of columns to span — this property essentially ‘interrupts’ the column flow and restarts it below the spanned element.

column-fill

Value: auto | balance
Initial value: balance

If you have set a height for your columnified element, setting column-fill to ‘auto’ will cause the columns to be ‘filled’ in turn, rather than have the content balanced equally between them.

CSS minifier and alphabetiser

Update: This project is now hosted on GitHub: https://github.com/barryvan/CSSMin/

There are quite a few CSS minifiers out there, which can bring the raw size of your CSS files down substantially. There are, however, significant gains to be made if the CSS is minified so that it gzips better. To that end, I’ve written a small Java application that will read in a CSS file and output its contents to stdout or another file in a format that’s optimised for gzipping.

The problem

A gzipped file will be stored most efficiently when there are many recurring strings in the file. This means that when writing CSS files, this code:

.pony {
border: solid red 1px;
font-weight: bold;
}
.lemur {
border: solid red 1px;
font-weight: normal;
}

will be better-compressed than this:

.pony {
border: solid red 1px;
font-weight: bold;
}
.lemur {
font-weight: normal;
border: red solid 1px;
}

In the first sample, notice that we have a very long string that occurs twice:

 {
border-style: solid red 1px;
font-weight: 

In the second sample, there are strings that occur more than once, but they’re much shorter. The gzip algorithm can, in the first case, replace that entire long string with a much shorter placeholder.

What it does

So, how can we optimise CSS for gzipping, then? A file that’s minified using this CSS Minifier will have these operations applied:

  • All comments removed.
  • The properties within all selectors ordered alphabetically.
  • The values for all properties ordered alphabetically.
  • All unnecessary whitespace removed.
  • Font weights replaced by their numeric counterparts (which are shorter).
  • Quotes stripped wherever possible.
  • As much text as possible transformed to lowercase.
  • Prefixed properties (for example, -moz-box-sizing) placed before the unprefixed variant (box-sizing).
  • Colours simplified from rgb() to six- or three-digit hex values, or simple names.
  • Units on values of 0 stripped.
  • Multi-parameter items simplified to as few parameters as possible.
  • Various other small tweaks and adjustments made.

By way of example, the following CSS snippet:

body {
  padding: 8px;
  margin: 0;
  background-color: blue;
  color: white;
  font-family: "Trebuchet MS", sans-serif;
}

h1 {
  margin: 0;
  padding: 0;
  font-size: 200%;
  color: #0F0;
  font-weight: bold;
}

p {
  margin: 0 0 2em;
  line-height: 2em;
}

would be formatted to the following (note that line breaks have been added for legibility — no line breaks appear in the final output):

body{background-color:blue;color:#fff;font-family:"trebuchet ms",sans-serif;
margin:0;padding:8px}h1{color:#0f0;font-size:200%;font-weight:700;margin:0;
padding:0}p{line-height:2em;margin:0 0 2em}

Compression results

These are the results of compressing the main CSS file for one of the webapps I develop at work.

  Original size (bytes) Gzipped size (bytes)
Plain 81938 12291
YUI 64434 10198
LotteryPost 63609 10165
CSS Drive 69275 10795
CSSMin 63791 9896

Download

Head over to GitHub to download the source.

Usage

First, if you haven’t done so yet, compile the code:

# javac CSSMin.java

Then, you can call the minifier by running

# java CSSMin in.css [out.css]

If you do not specify an output file, the resultant CSS will be printed to stdout (and can then be redirected as you wish).

Contact

If you have any questions or comments about this app, or if you find a bug or some weird behaviour, just comment on this post, and I’ll see what I can do.

You can also raise issues on GitHub, fork the project, commit changes, and more.

If you find this utility useful, let me know!