When And How To Use CSS Multi-Column Layout
When And How To Use CSS Multi-Column Layout
Rachel Andrew2019-01-11T15:00:30+02:002019-01-11T14:18:35+00:00
In all of the excitement about CSS Grid Layout and Flexbox, another layout method is often overlooked. In this article I’m going to take a look at Multi-column Layout — often referred to as multicol or sometimes “CSS Columns”. You’ll find out which tasks it is suited for, and some of the things to watch out for when making columns.
What Is Multicol?
The basic idea of multicol, is that you can take a chunk of content and flow it into multiple columns, as in a newspaper. You do this by using one of two properties. The column-count
property specifies the number of columns that you would like the content to break into. The column-width
property specifies the ideal width, leaving the browser to figure out how many columns will fit.
It doesn’t matter which elements are inside the content that you turn into a multicol container, everything remains in normal flow, but broken into columns. This makes multicol unlike other layout methods that we have in browsers today. Flexbox and Grid for example, take the child elements of the container and those items then participate in a flex or grid layout. With multicol, you still have normal flow, except inside a column.
In the below example I am using column-width
, to display columns of at least 14em
. Multicol assigns as many 14em
columns as will fit and then shares out the remaining space between the columns. Columns will be at least 14em
, unless we can only display one column in which case it may be smaller. Multicol was the first time that we saw this kind of behavior in CSS, columns being created which were essentialy responsive by default. You do not need to add Media Queries and change the number of columns for various breakpoints, instead we specify an optimal width and the browser will work it out.
See the Pen Smashing Multicol: column-width by Rachel Andrew (@rachelandrew) on CodePen.
Styling Columns
The column boxes created when you use one of the column properties can’t be targeted. You can’t address them with JavaScript, nor can you style an individual box to give it a background color or adjust the padding and margins. All of the column boxes will be the same size. The only thing you can do is add a rule between columns, using the column-rule property, which acts like border. You can also control the gap between columns using the column-gap
property, which has a default value of 1em
however you can change it to any valid length unit.
See the Pen Smashing Multicol: column styling by Rachel Andrew (@rachelandrew) on CodePen.
That is the basic functionality of multicol. You can take a chunk of content and split it into columns. Content will fill the columns in turn, creating columns in the inline direction. You can control the gaps between columns and add a rule, with the same possible values as border. So far so good, and all of the above is very well supported in browsers and has been for a long time, making this spec very safe to use in terms of backwards compatibility.
There are some further things you might want to consider with your columns, and some potential issues to be aware of when using columns on the web.
Spanning Columns
Sometimes you might like to break some content into columns, but then cause one element to span across the column boxes. Applying the column-span
property to a descendent of the multicol container achieves this.
In the example below, I have caused a
element to span across my columns. Note that when you do this, the content breaks into a set of boxes above the span, then starts a new set of column boxes below. The content doesn’t jump across the spanned element.
The
column-span
property is currently being implemented in Firefox and is behind a feature flag.See the Pen Smashing Multicol: column-span by Rachel Andrew (@rachelandrew) on CodePen.
Be aware that in the current spec, the values for
column-span
are eitherall
ornone
. You can’t span just some of the columns, but you can get the kind of layout you might see in a newspaper by combining multicol with other layout methods. In this next example, I have a grid container with two column tracks. The left-hand track is2fr
, the right-hand track1fr
. The article in the left-hand track I have turned into a multicol container with two tracks, it also has a spanning element.On the right, we have an aside which goes into the second Grid column track. By playing around with the various layout methods available to us, we can figure out exactly which layout method suits the job at hand — don’t be afraid to mix and match!
See the Pen Smashing Multicol: mixing layout methods by Rachel Andrew (@rachelandrew) on CodePen.
Controlling Content Breaks
If you have content containing headings, then you probably want to avoid the situation where a heading ends up as the last thing in a column with the content going into the next column. If you have images with captions then the ideal situation would be for the image and caption to stay as one unit, not becoming split across columns. To deal with these problems CSS has properties to control where the content breaks.
When you split your content into columns, you perform what is known as fragmentation. The same is true if you split your content between pages, such as when you create a stylesheet for a print context. Therefore, multicol is closest to Paged Media than it is to other layout methods on the web. Because of this, for several years the way to control breaks in the content has been to use the
page-break-
properties which were part of CSS2.1.
page-break-before
page-break-after
page-break-inside
More recently the CSS Fragmentation specification has defined properties for fragmentation which are designed for any fragmented context, the spec includes details for Paged Media, multicol and the stalled Regions spec; Regions also fragments a continuous piece of content. By making these properties generic they can apply to any future fragmented context to, in the same way that the alignment properties from Flexbox were moved into the Box Alignment spec in order that they could be used in Grid and Block layout.
break-before
break-after
break-inside
As an example, I have used
break-inside avoid
on the