Abstract

This specification describes multi-column layouts in CSS, a style sheet
language for the web. Using functionality described in the specification,
content can be flowed into multiple columns with a gap and a rule between
them.

Status of this
document

This section describes the status of this document at the time of
its publication. Other documents may supersede this document. A list of
current W3C publications and the latest revision of this technical report
can be found in the W3C technical reports
index at http://www.w3.org/TR/.

A Candidate Recommendation is a document that has been widely reviewed
and is ready for implementation. W3C encourages everybody to implement
this specification and return comments to the (archived) public
mailing list
www-style@w3.org (see instructions). When sending
e-mail, please put the text “css3-multicol” in the subject,
preferably like this: “[css3-multicol]
…summary of comment…”

Publication as a Candidate Recommendation does not imply endorsement by
the W3C Membership. This is a draft document and may be updated, replaced
or obsoleted by other documents at any time. It is inappropriate to cite
this document as other than work in progress.

This document has been a Working Draft in the CSS Working Group for
several years. Multi-column layouts are traditionally used in print. On
screen, multi-column layouts have been considered experimental, and
implementation and use experience was deemed necessary in order to
proceed. Several implementations have occurred over the past years, and
this specification incorporates useful feedback from implementors as well
as authors and users.

The specification was updated in April 2011 to correct a contradiction
between the text and the pseudo-algorithm in section 3.4. The
pseudo-algorithm was corrected and also made easier to read. The wording
of a few other sections was improved in places, without changes to the
functionality.

This document will remain Candidate Recommendation at least until 12 May
2011. See the CR exit criteria.

1. Introduction

This module describes multi-column layout in CSS. By using functionality
described in this document, style sheets can declare that the content of
an element is to be laid out in multiple columns.

On the Web, tables have also been used to describe multi-column layouts.
The main benefit of using CSS-based columns is flexibility; content can
flow from one column to another, and the number of columns can vary
depending on the size of the viewport. Removing presentation table markup
from documents allows them to more easily be presented on various output
devices including speech synthesizers and small mobile devices.

Multi-column layouts are easy to describe in CSS. Here is a simple
example:

body { column-width: 12em }

In this example, the body element is set to
have columns at least ‘12em’ wide. The
exact number of columns will depend on the available space.

The number of columns can also be set explicitly in the style sheet:

body { column-count: 2 }

In this case, the number of columns is fixed and the column widths will
vary depending on the available width.

The shorthand ‘columns’ property can be used to set
either, or both, properties in one declaration.

In these examples, the number of columns, the width of columns, and
both the number and width are set, respectively:

body { columns: 2 }
body { columns: 12em }
body { columns: 2 12em }

However, as described below, setting both the width and number of
columns rarely makes sense.

Another group of properties introduced in this module describe gaps and
rules between columns.

body {
column-gap: 1em;
column-rule: thin solid black;
}

The first declaration in the example above sets the gap between two
adjacent columns to be 1em. Column gaps are similar to padding areas. In
the middle of the gap there will be a rule which is described by the
‘column-rule’ property.

The values of the ‘column-rule’ property are similar to those
of the CSS border properties. Like ‘border’, ‘column-rule’ is a shorthand property.

In this example, the shorthand ‘column-rule’ declaration from the above
example has been expanded:

If all column properties have their initial value, the layout of an
element will be identical to a multi-column layout with only one column.

2. The multi-column
model

A multi-column element (or
multicol element for short) is an element whose ‘column-width’
or ‘column-count’ property is not ‘auto’ and therefore acts as a container for
multi-column layout.

In the traditional CSS box model, the content of an element is flowed
into the content box of the corresponding element. Multi-column layout
introduces a new type of container between the content box and the
content, namely the column box (or
column for short). The content of a multicol element is flowed
into its column boxes.

Column boxes in a multi-column element are arranged into rows.
Like table cells, the column boxes in a row are ordered in the inline
direction of the multicol element. The column width is the length
of the column box in the inline direction. The column height is
the length of the column box in the block direction. All column boxes in a
row have the same column width, and all column boxes in a row have the
same column height. Within each row in the multi-column element, adjacent
column boxes are separated by a column gap, which may contain a
column rule. All column gaps in the same row are equal. All
column rules in the same row are also equal, if they appear; column rules
only appear between columns that both have content.

In the simplest case a multicol element will contain only one row of
columns, and the height of each column will be equivalent to the used
height of the multi-column element's content box. If the multi-column
element is paginated, the height of each row is constrained by the page
and the content continues in a new row of column boxes on the next page; a
column box never splits across pages. The same effect occurs when a spanning element divides the
multi-column element: the columns before the spanning element are balanced
and shortened to fit their content. Content after the spanning element
then flows into a new row of column boxes.

It is not possible to set properties/values on column boxes. For
example, the background of a certain column box cannot be set and a column
box has no concept of padding, margin or borders.

Future specifications may add additional functionality. For
example, columns of different widths and different backgrounds may be
supported.

Column gaps (yellow) and column rules (green) are shown in this sample
rendition of a multi-column element with padding (blue). The blue and
yellow is present for illustrational purposes only. In actual
implementations these areas will be determined by the background.

The nonsensical text in the example is the English alphabet which shows
how text flows from one column to another. To simplify the visualization,
the textual content of the different examples vary slightly.

Column boxes act as the containing block for their content. That is,
column boxes behave like block-level, table cell, and inline-block boxes
as per CSS 2.1, section 10.1, item 2 [CSS21]. However, column boxes do not
establish containing blocks for elements with ‘position: fixed’ or ‘position: absolute’.

In this example, the width of the image is set with these rules:

img { display: block; width: 100% }

Given that the width is calculated relative to the column box, the
image will be as wide as the column box:

A multi-column element establishes a new block formatting context, as
per CSS 2.1 section 9.4.1.

A top margin set on the first child element of a multicol element will
not collapse with the margins of the multicol element.

Nested multi-column elements are allowed, but there may be
implementation-specific limits.

3. The
number and width of columns

Finding the number and width of columns is fundamental when laying out
multi-column content. When the block direction is unconstrained and no
column breaks are added through style sheets, these two properties
determine the outcome:

means that the column width will be determined by other properties
(e.g., ‘column-count’, if it has a non-auto
value).

<length>

describes the optimal column width. The actual column width may be
wider (to fill the available space), or narrower (only if the available
space is smaller than the specified column width). Specified values must
be greater than 0.

The available space is smaller than the specified column width and the
actual column width will therefore be decreased.

To ensure that ‘column-width’ can be used with vertical
text, column width means the length of the line boxes inside the columns.

The reason for making ‘column-width’ somewhat flexible is to
achieve scalable designs that can fit many screen sizes. To set an exact
column width, all length values (in horizontal text these are:
‘width’, ‘column-width’,
‘column-gap’, and ‘column-rule-width’) must be specified.

means that the number of columns will be determined by other
properties (e.g., ‘column-width’, if it has a non-auto
value).

<integer>

describes the optimal number of columns into which the content of the
element will be flowed. Values must be greater than 0. If both ‘column-width’
and ‘column-count’ have non-auto values, the
integer value describes the maximum number of columns.

3.4. Pseudo-algorithm

The pseudo-algorithm below determines the used values for ‘column-count’
(N) and ‘column-width’ (W). There are two other
variables in the pseudo-algorithm:

available-width: if the used width of the multi-column
element has not been determined when the ‘column-count’
and ‘column-width’ must be determined (e.g.,
if it is floating with a ‘width’
of ‘auto’ as per CSS 2.1 section
10.3.5) this variable is unknown, otherwise it is the same
as the used width of the multi-column element. In vertical text, the used
height replaces used width in this calculation.

shrink-to-fit: this variable represents the result of a
shrink-to-fit computation. CSS does not define the exact
algorithm.

In paged media, user agents may perform this calculation on a per-page
basis.

Note that, in most cases, only one of ‘column-width’
and ‘column-count’ affect the layout. If
‘column-width’ has a value other than
‘auto’, ‘column-count’
indicates the maximum number of columns. However, both ‘column-width’
and ‘column-count’ are honored when the width
of the element has not been determined. This can, e.g., be the case for
table cells and floats.

3.5. Stacking context

All column boxes in a multi-column element are in the same stacking
context and the drawing order of their contents is as specified in CSS
2.1.

4. Column gaps and
rules

Column gaps and rules are placed between columns in the same multicol
element. The length of the column gaps and column rules is equal to the
length of the columns. Column gaps take up space. That is, column gaps
will push apart content in adjacent columns (within the same multicol
element).

A column rule is drawn in the middle of the column gap with the
endpoints at opposing content edges of the multicol element. Column rules
do not take up space. That is, the presence or thickness of a column rule
will not alter the placement of anything else. If a column rule is wider
than its gap, the column rule will overlap adjacent column boxes, and
possibly extend outside the box of the multicol element. Column rules are
painted just above the background of the multicol element. This allows
child elements with ‘z-index’
values to be on top of column rules. Column rules are only drawn between
two columns that both have content.

If a tall image is moved to a column on the next page to find room for
it, its natural column may be left empty. If so, the column is is still
considered to have content for the purpose of deciding if the column rule
should be drawn.

5. Column breaks

When content is laid out in multiple columns, the user agent must
determine where column breaks are placed. The problem of breaking content
into columns is similar to breaking content into pages.

Three new properties are introduced to allow column breaks to be
described in the same properties as page breaks: ‘break-before’,
‘break-after’, and ‘break-inside’.
These properties take the same values as ‘page-break-before’, ‘page-break-after’, and ‘page-break-inside’ [CSS21]. In addition, some new
keyword values are added.

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.

This specification adds the following new values:

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.

When a page or column break splits a box, the box's margins, borders,
and padding have no visual effect where the split occurs. However, the
margin immediately after a forced page/column break will be preserved. A
forced page/column break is a break that does not occur naturally.

In the future, new properties may describe alternate ways to
handle margins, borders and padding around page/column breaks.

In this example, forced column breaks appear before h2
elements and after img elements:

This property describes how many columns an element spans across. Values
are:

none

The element does not span multiple columns.

all

The element spans across all columns. Content in the normal flow that
appears before the element is automatically balanced across all columns
before the element appears. The element establishes a new block
formatting context.

An element that spans more than one column is called a spanning element.

In this example, an h2 element has been added to the
sample document after the first sentence in the fourth sentence (i.e.,
after the word "jkl."). This styling applies:

h2 { column-span: all; background: silver }
img { display: none }

By setting ‘column-span’ to ‘all’, all content that appear before the
h2 element is shown before the h2 element.

A spanning element takes up more space than the element would take up
otherwise. When space is limited, it may be impossible to find room for
the spanning element. In these cases, user agents may treat the element as
if ‘none’ had been specified on
this property.

This is a variation of the previous example. In this example, the H2
element appears later in the content, and the height of the multicol
element is constrained. Therefore, the H2 element appears in the overflow
and there is not room to make the element spanning. As a result, the
element appears as if ‘column-span:
none’ was specified.

7. Filling columns

There are two strategies for filling columns: columns can either be
balanced, or not. If columns are balanced, UAs should minimize the
variation in column length. Otherwise, columns are filled sequentially and
some columns may end up partially filled, or with no content at all. In
any case, the user agent should try to honor the ‘widows’ and ‘orphans’ properties.

9. Conformance

Conforming UAs must flow the content of an element into several columns
according to this specification.

The conformance requirements are expressed with a combination of
descriptive assertions and RFC 2119 terminology. The key words "MUST",
"MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT",
"RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this
document are to be interpreted as described in RFC 2119. However, for
readability, these words do not appear in all uppercase letters in this
specification. All of the text of this specification is normative except
sections explicitly marked as non-normative, examples, and notes. [RFC2119]

9.1. CR exit criteria

As described in the W3C process document, a Candidate
Recommendation (CR) is a specification that W3C recommends for use on
the Web. The next stage is Recommendation, when the specification
is sufficiently implemented.

For this specification to be proposed as a W3C Recommendation, the
following conditions shall be met. There must be at least two independent,
interoperable implementations of each feature. Each feature may be
implemented by a different set of products, there is no requirement that
all features be implemented by a single product. For the purposes of this
criterion, we define the following terms:

independent

each implementation must be developed by a different party and cannot
share, reuse, or derive from code used by another qualifying
implementation. Sections of code that have no bearing on the
implementation of this specification are exempt from this requirement.

interoperable

passing the respective test case(s) in the official CSS test suite,
or, if the implementation is not a Web browser, an equivalent test. Every
relevant test in the test suite should have an equivalent test created if
such a user agent (UA) is to be used to claim interoperability. In
addition if such a UA is to be used to claim interoperability, then there
must one or more additional UAs which can also pass those equivalent
tests in the same way for the purpose of interoperability. The equivalent
tests must be made publicly available for the purposes of peer review.

implementation

a user agent which:

implements the specification.

is available to the general public. The implementation may be a
shipping product or other publicly available version (i.e., beta
version, preview release, or nightly build). Non-shipping
product releases must have implemented the feature(s) for a period of
at least one month in order to demonstrate stability.

is not experimental (i.e., a version specifically designed to pass
the test suite and is not intended for normal usage going forward).

A minimum of sixth months of the CR period must have elapsed. This is to
ensure that enough time is given for any remaining major errors to be
caught.

Features will be dropped if two or more interoperable implementations
are not found by the end of the CR period.

Features may/will also be dropped if adequate/sufficient (by judgment of
CSS WG) tests have not been produced for those feature(s) by the end of
the CR period.