Things We Can’t (Yet) Do In CSS

Things We Can’t (Yet) Do In CSS

Things We Can’t (Yet) Do In CSS

Rachel Andrew

Building “magazine-style layouts” by using CSS Grid has become something of a pastime of CSS fans, keen to play with the capabilities of new Grid Layout. It’s something I’ve done myself as well as with people who’ve attended my workshops. However, I always have to pick the layouts carefully because, in truth, there are a number of very common print layout patterns that we can’t currently do on the web.

In a lot of cases, however, we can do these things with CSS —just not on the web. If you have read some of my previous articles, such as “Designing For Print With CSS”, you’ll be aware that CSS is also used for print formatting via user agents designed for outputting to PDF. These user agents have often implemented specifications or extensions to specifications that have never been implemented in continuous media, such as the scrolling and non-paged content that we have on the web.

In addition, we have some CSS specifications that haven’t yet been implemented by a browser or have only been implemented in an experimental way on one browser. We also have some things which are just at the discussion phase, perhaps as a note in the current level of a spec as to where we might take it in future.

So while most of my articles are about things we can do, this one is about things we can’t but that perhaps we might be able to do in the future. Take a look.

Floating Things From Specific Points

On the web, a floated element is taken out of flow and following text wraps around it (due to the line boxes of the following text becoming shortened). Therefore, you only have the option to float a thing to the left or right.

In print, however, you often need to float items to specific places on the page. For example, by floating an element to the top or bottom of a page.

When creating a printed document, you define the size of your pages by using the @page rule, and then your content flows into those pages. By increasing the amount of content or the font size of the text, more pages will be created. Therefore, you might have an element that you know you want to display at the top of the page it appears in, but don’t know exactly on which page it will be.

The CSS Specification that deals with this behavior is called Page Floats. Your image would display in the normal flow of the content — just as on the web — except that the content is fragmented into pages. When the page with the image is encountered, the image is moved out of the normal flow and floated to the top of the page where it appears on. (Content that would have been above the image will display below it and normal flow resumes.)

img {
    float-reference: page;
    float: top;
}
A diagram showing two pages, one with an image partway through the content the other with the image at the top
On the left is the image in normal flow, using Page Floats it can be made to appear at the top of the page with the rest of the content coming after it (Large preview)

There is an issue raised against the Page Floats specification to rename it, as there are use cases for this kind of pattern continuous media, e.g. in a multicolumn layout. Currently, if you float an item inside a column, it behaves in the same way as a float in regular normal flow. Assuming there is room, the line boxes of the following items will be shortened and text will wrap around the float within the column.

By using a “page float”, we could float an item to the top of the column that could give you much more control over the placement of elements within the flow of content in a multicolumn context.

Columns are essentially just like pages; we fragment our content between column boxes in the same way that we fragment our content between pages. Therefore, a more generic name would make sense in terms of this behavior being the same for columns and pages.

There are more examples of Page Floats in the excellent exploration of the subject, “Paged Media Approaches: Page Floats” by Julie Blanc.

Overflow In The Block Dimension For Multicol

The concept of “page” floats, would be even more necessary if we were to implement block dimension overflow columns in Multicol. Currently, if you fix the height of a multicol container, additional columns will be created in the inline direction causing an inline scrollbar.

See the Pen Smashing Multicol: overflow columns by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Smashing Multicol: overflow columns by Rachel Andrew (@rachelandrew) on CodePen.

As I describe in my article “When And How To Use Multiple-Column Layout”, in the CSS Working Group we have considered how we might specify overflow in the block dimension. This would allow us to fix the height of the multicol container in the block dimension, and if there was more content that could fit, create another row of columns below and fill that with content.

How does this tie into Page Floats? Well, in this scenario, you would want more control over where images and other elements end up in these rows of columns. I wouldn’t want, for example, an image to have one line of text below it before the content, and then fragmented to form the next row of columns. Page Floats would enable me to specify that images in that situation would be floated to the bottom of the column or to the top of the first column in the new row.

Spanning n Columns

In the next version of Firefox (Firefox 71), the column-span property from the Multiple-Column Layout specification is implemented, meaning that all of our web browsers implement column-span. The column-span property can take one of two values, all or none. If the value is all, it spans all of the columns; if it is none (which is the initial value), it doesn’t span.

What about multi-column layouts with elements that span some columns? This is a pattern I find in print design quite frequently. The spanning element will generally be at the top or bottom of the page, shortening the columns below or above it.

A photograph of a three column magazine layout, with a quote spanning two columns
A quote spans two columns in this article (Large preview)

This is not currently possible on the web, and we don’t have a spec yet for this behavior, however, some print user agents have already implemented an extension to the spec to do this. By using Prince, I can use the following CSS to span two columns:

img {
    float: column-top-corner;
    column-span: 2;
}

This would enable an element to be floated to the top corner using the Prince version of Page Floats, and then span two of the columns. The rest of the content flows into column boxes as is normal when using multicol. In Prince, the spanning of some columns is tied to floated elements; non-floated elements behave as per the Level 1 multicol spec and can only span all or none.

Specifying this raises some interesting issues. Currently, when we introduce a spanner in multicol, the spanning element essentially creates a row of column boxes above it, and a row of column boxes below. The content doesn’t jump over the spanning element and continue — as you can see in his next CodePen.

See the Pen Smashing Multicol: column-span by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Smashing Multicol: column-span by Rachel Andrew (@rachelandrew) on CodePen.

What should happen if we have an item spanning two out of three columns that is placed in the middle of the content? In many of the print examples I have seen, the content jumps the spanner when encountering these partial spans, rather than behaving as multicol does today.

A photograph of a magazine article
In this example, the column content jumps over the spanner and continues. (Large preview)

There are further explorations of column-spanning and extensions ot floats in the CSS Figures Living Idea document. In an older post of mine, I also explored some of these ideas, “Thinking About Page Floats, Figures, Regions And Grids”.

Different Sized Columns In Multicol

Both Flexbox and Grid Layout give us the ability to do columns which are of different sizes that remain in proportion to one another as they flex. Multicol, however, can only split content into equal-sized columns. It is common in print design to have columns of unequal sizes.

Now that Flexbox and Grid have this behavior it makes sense that multicol should follow suit and allow for different column sizes. Perhaps something to consider for level 2 of the Multicol specification.

Text Wrapping All Sides Of An Element

You will have trouble opening a magazine and not spotting something like the image below. Content wrapping all sides of a quote, callout or image. It is a very common pattern and seems reasonable as a pattern we might want to use on the web.

The article title is centered and wrapped by text set as two columns
Content wrapping three sides of a floated element in this article in Monocle (Large preview)

We do have a CSS Specification that enables this behavior. CSS Exclusions, at one time bundled with the CSS Shapes specification as CSS Exclusions and Shapes, defines the wrap-flow and wrap-through properties. Exclusions doesn’t define positioning. Instead, you would use it with another positioning method — most likely CSS Grid Layout. This enables a pattern such as in the image below (taken in IE11):

An image wrapped on all sides with text
Exclusions in Internet Explorer 11 (Large preview)

Note: If you have a pre-Chromium Edge or Internet Explorer 11 installed, see the CodePen example.

The above example works in Internet Explorer 11 (or pre-Chromium Edge) using the -ms prefixed grid version. Internet Explorer is the only browser to have attempted to implement the property. I am very keen to see implementations of exclusions. I think it solves a number of issues that we have with editorial layouts on the web.

Note: For more, see my post “Editorial Layouts, Exclusions and Grid” or read this issue on the CSS Working Group Drafts repository.

Disconnected Text Flows

Print design often includes content that flows in a similar way to multicol, however, the content boxes are not connected to each other.

You can see an example below from the magazine Monocle:

A photograph of a magazine article with text, quotes and images in boxes
The content of this article flows between two boxes (Large preview)

This is very difficult to do on the web. If you know how much content you are likely to have, you can make these layouts using Grid in many cases. However, they are then fairly fragile; they rely on us understanding how much content we have and in breaking it up into separate HTML elements. This will usually require us to wrap chunks of content in a div in order to have an element to position on the grid.

A more ideal scenario would be to keep the article as one (properly marked-up thread of content) which could flow into defined areas in the layout.

A diagram showing some content on one side, which is then displayed in different boxes of the grid
An article which is then displayed in disconnected areas of the grid

We do have a specification that details something like this: the CSS Regions specification. This was implemented in IE10 (and is therefore in pre-Chromium Edge), and was also in Chrome and WebKit before being removed. Can I use shows the state of affairs.

Chart showing that Regions was in several browsers but has now been removed
Can I Use CSS Regions (Large preview)

There were some significant issues with the Regions specification in that it required HTML elements to be present to flow the content into. Unlike multicol, in which anonymous column boxes are generated to hold the content, Regions requires an existing HTML element to host the content. So while you did get the nice behavior of content flowing through these disconnected boxes, you still had to work out how many boxes you needed and create empty divs to hold that content.

Your solution for more content than would fit would be to have a final auto-sized element to “mop up” this extra content without a home. This doesn’t seem like a very elegant solution!

For more information on the problems with the Regions spec as it currently stands, see “CSS Regions Considered Harmful.”

A Future For Regions?

I would be very keen to see something like Regions make a comeback. I think that we know more now about the sorts of layouts that we want to build — now that we have Grid Layout. Regions would enable a sensibly marked-up article to flow through defined boxes in a grid layout, and enable exactly the sort of layouts we see in magazines. From the very simple — skipping a center column that contains a quote or image — to complex sets of boxes and images.

In the Paged Media specification, we have a model for a defined box which is duplicated over and over to create as many pages as needed for the content we have — you don’t need to define those pages upfront. In the developing idea for block dimension overflow columns in multicol, we are considering a model where new rows of columns can be created, as many as are needed until we run out of content. Could we see a future for Regions where we can define a pattern of areas and keep repeating that pattern until we run out of content to fill it?

A diagram showing a longer article flowing through two grids of boxes
The article is flowed into the layout, once all the boxes are filled the pattern repeats

Whatever solution is found for Regions, it would reply on solid support for Fragmentation in browsers. Once you break your content across Regions, you will be keen to avoid things like a heading becoming the last thing in a Region — with the associated content somewhere completely disconnected. As with the multicol ideas, I think it would also require support for Page Floats so that we’re able to better control how certain elements display in a Region and stop orphan lines displaying below an image as the content fragments to another Region. In addition Regions would add to the potential of confusing content re-ordering on the web, therefore I think there are a number of related things to get right before we could see a robust and elegant solution to this problem.

Share Your Use Cases

I would love to know if you have use cases for any of the above types of layouts, or if there are other layouts you would love to do but are impossible (or only possible in a fragile way). Let me know in the comments — or even better — write up the issue on your own site and drop a link into the comments section below. Adding new features to CSS starts with understanding what the use cases and requirements are.

You can also follow the discussion on all CSS specifications at the CSS Working Group GitHub repo and Issues List.

Smashing Editorial (il)

When And How To Use CSS Multi-Column Layout

When And How To Use CSS Multi-Column Layout

When And How To Use CSS Multi-Column Layout

Rachel Andrew

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 <blockquote> 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 either all or none. 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 is 2fr, the right-hand track 1fr. 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 <figure> element, to prevent the caption being detached from the image. A supporting browser should keep the figure together even if that causes the columns to look unbalanced.

See the Pen Smashing Multicol: break-inside by Rachel Andrew (@rachelandrew) on CodePen.

Unfortunately, support for these properties in multicol is pretty patchy. Even where supported they should be seen as a suggestion due to the fact that it would be possible to make so many requests while trying to control breaking, that essentially the browser can’t really break anywhere. The spec does define priorities in this case, however it is probably more useful for you to control only the most important cases.

The Problem Of Columns On the Web

One reason why we don’t see multicol used much on the web is the fact that it would be very easy to end up with a reading experience which made the reader scroll in the block dimension. That would mean scrolling up and down vertically for those of us using English or another vertical writing mode. This is not a good reading experience!

If you fix the height of the container, for example by using the viewport unit vh, and there is too much content, then overflow will happen in the inline direction and so you get a horizontal scrollbar instead.

See the Pen Smashing Multicol: overflow columns by Rachel Andrew (@rachelandrew) on CodePen.

Neither of these things are ideal, and making use of multicol on the web is something we need to think about very carefully in terms of the amount of content we might be aiming to flow into our columns.

Block Overflow Columns

For Level 2 of the specification, we are considering how to enable a method by which overflow columns, those which currently end up causing the horizontal scrollbar, could instead be created in the block direction. This would mean that you could have a multicol container with a height, and once the content had made columns which filled that container, a new set of columns would be created below. This would look a little like our spanning example above, however, instead of having a spanner causing the new column boxes to start, it would be the overflow caused by a container with a restriction in the block dimension.

This feature would make multicol far more useful for the web. While we are a little way off right now, you can keep an eye on the issue in the CSS Working Group repo. If you have additional use cases for this feature do post them, it can really help when designing the new feature.

What Is Multicol Useful For Today?

With the current specification, splitting all of your content into columns without consideration for the problems of scrolling isn’t advised. However, there are some cases where multicol is ideal on the web. There are enough uses cases to make it something you should consider when looking at design patterns.

Collapsing Small UI Or Text Elements

Multicol can be useful in any place where you have a small list of items that you want to take up less space. For example a simple listing of checkboxes, or a list of names. Often in these scenarios, the visitor is not reading down one column and then going back to the top of the next, but scanning the content for a checkbox to click or an item to select. Even if you do create a scrolled experience, it may not be an issue.

You can see an example of multicol used in this way by Sander de Jong on the DonarMuseum website.

Names are arranged into multiple columns on the DonarMuseum website
On DonarMuseum, we can see multicol used to display lists of names. (Image source) (Large preview)

Known Small Amounts Of Content

There are times when we design a site where we know that some piece of content is relatively small, and will fit on the majority of screens without causing unwanted scrolling. I’ve used multicol on Notist presentation pages, for the introduction to a talk.

Andy Clarke designed a lovely example for the Equfund website.

A two-column layout including various content
On the Equfund website, you can see how different HTML elements remain in normal flow while displayed inside columns. (Image source) (Large preview)

To avoid the possibility of very small screens causing scrolling, remember that you can use media queries to check for height as well as width (or in a logical world, block as well as inline). If you only enable columns at a breakpoint which has a min-height large enough for their content, this can save users of very small devices having a poor scrolling experience.

Masonry-Like Display Of Content

Another place where Multiple-column Layout works beautifully is if you want to create a Masonry type of display of content. Multicol is the only layout method that will currently create this kind of layout with unequal height items. Grid would either leave a gap, or stretch the items to make a strict two-dimensional grid.

Veerle Pieters has a beautiful example of using multicol in this way on her inspiration page.

An arrangement of multiple boxes in columns designed by Veerle Pieters
In this design by Veerle Pieters, multicol is used to layout multiple boxes or cards as columns. (Large preview)

Grid And Flexbox Fallbacks

The column- properties can also be used as a fallback for Grid and Flex layout. If you specify one of the properties on a container, then turn that container into a Flex or Grid layout by using display: flex or display: grid any column behavior will be removed. If you have, for example, a cards layout that uses Grid Layout, and the layout would be readable if it ran in columns rather than across the page, you could use multicol as a simple fallback. Browsers that do not support Grid will get the multicol display, those which support Grid will get the Grid Layout.

Don’t Forget Multicol!

Fairly frequently I answer Grid and Flexbox questions where the answer is to not use Grid or Flexbox, but instead to look at Multicol. You probably won’t use it on every site, but when you come across a use case it can be really helpful. Over at MDN there are useful resources for multicol and the related fragmentation properties.

If you have used multicol on a project, perhaps drop a note in the comments, to share other ways in which we can use the feature.

Smashing Editorial (il)