Publish date:



Despite predating both Grid and Flexbox, Multi-column Layout represents—at least to me—an even more radical departure from the way we normally do and think about CSS layout. Dividing just one element into a multi-column representation of its contents feels weird, heretical even.

Setting a multi-column context means asking (flow) content to progress, by column, in a horizontal direction. This invokes one of two issues, depending on whether you set a height on the element.

With no set height, there’s no limit to the height of the columns. This will result in vertical overflow, and the necessity to scroll down and up the page to read each successive column. Many are likely to find this arduous.

A zig zag line illustrates the reading direction of multiple columns

With a set height, columns are forced to spawn in the inline (horizontal) direction, creating horizontal overflow. Setting overflow: auto frames this correctly.

.columns {

height: 25vh;

columns: 30ch;

overflow: auto;


However, despite the increasing popularity of scrolling menus and other such patterns harnessing horizontal scrolling, it is still an unconventional interaction paradigm — and unconventional patterns are liable to be misapprehended by users. There are ways to increase perceived affordance, of course—perhaps by adding some custom styling to the scrollbar (-webkit-scrollbar), or providing some overflow-dependent shadows. But this may not be enough.

Quantity-dependent columns

One thing I have been experimenting with is the application of multiple columns in response to content quantity.

Let’s say I have a bullet list, and let’s assume each bullet point is likely to be relatively short; no more than a sentence. There’s no benefit to dividing the list into columns when there are only a few points. But the overall height of the list is shortened (and the chance of the reader being able to see the whole list without scrolling is increased) when a long list is divided into two.

Left: a one column list breeches the viewport at the top and bottom. Right: the list is split into two and can now be contained by the viewport height

In the following example, the list is split into two columns where there are 5 or more list items.

ol, ul {

columns: 2;

column-gap: 1rem;


li {

column-span: all;


li:nth-last-child(n 5),

li:nth-last-child(n 5) ~ * {

column-span: none;


By default, column-span is set to all, meaning each list item ignores the two-column mandate. A quantity query (the final declaration block) then resets column-span to none where 5 or more list items are present. Despite the misleading none value, this means list items will span one of the two columns.

Three columns. The first element in just one column wide because it has column-span: none. The second element is the width of all three columns, because it has column-span: all.

To follow is a live demo. Try opening up developer tools and removing a couple of list items.

  • Orci Ultrices Mi Varius Ante Nisl Ac Pretium Egestas Semper
  • Nec Erat Imperdiet Tincidunt Ligula Urna Commodo Mauris
  • Convallis Tincidunt Enim Eros Faucibus Ligula Arcu Eget Feugiat
  • Leo Ante Tellus Nibh Morbi Nec Tellus Erat
  • Cubilia Feugiat Accumsan Euismod Dolor Semper Orci Ligula Dolor Orci
  • Felis Odio Bibendum Vestibulum Ante Erat Cras Dolor In Non

Block direction overflow

As Rachel Andrew has proposed, it would be beneficial to be able to control both the inline and block overflow direction. The support of block overflow would mean we could assume control over both column width and height. So long as the chosen height is no taller than the current viewport, the repetitive vertical scrolling issue described above disappears.

Two rows, each of four columns of text. The first row is entirely within the height of the viewport

Reading down columns no longer necessitates vertical scrolling.

How block overflow direction is implemented and exposed is still up for grabs so, if you have any ideas, you may want to voice them.

My initial thinking is that a column-height property should be supported alongside column-width and column-count. The columns shorthand property would then need to take height as a third parameter.

Currently, columns takes column-width and column-count in any order—presumably because parsing can identify which is a length value and which is just an integer. This becomes more complex with two length parameters, so an expected order for these properties may need to be set. If that expected order is width-before-height, then the following values would be considered valid (where 30ch represents the width, and 25vh represents the height):

.columns {

columns: 30ch 25vh;


.columns {

columns: 30ch 25vh 3;


.columns {

columns: 30ch 3 25vh;


.columns {

columns: 3 30ch 25vh;


It’s worth noting that ‘hard-coding’ a column-count is not likely to be useful in most cases, since both columns and rows are now being dynamically provisioned based on the available space. It’s also worth noting that column-width sets an ideal width, not a fixed one, much like flex-basis. This eliminates overlaps and gaps.

The column-gap property injects space between columns. With support of column-height in place, row-gap would have to be supported as well. Although you are probably more familiar with the CSS Grid-specific properties grid-gap, grid-row-gap, and grid-column-gap, Firefox already supports the generic gap, row-gap, and column-gap properties for Flexbox. The intention is to normalize gap across the Grid, Flexbox, and Multi-column modules.


  1. Howdy! This is my first comment here so I just wanted to give a quick
    shout out and say I genuinely enjoy reading your blog posts.
    Can you recommend any other blogs/websites/forums that
    go over the same topics? Thanks for your time!

  2. Great beat ! I would like to apprentice while you amend your site, how could
    i subscribe for a blog site? The account aided
    me a acceptable deal. I had been a little bit acquainted of this your broadcast offered bright
    clear idea

  3. Good day! I know this is somewhat off topic but I was wondering if you knew
    where I could find a captcha plugin for my comment form?
    I’m using the same blog platform as yours and I’m having difficulty finding one?

    Thanks a lot!

  4. Howdy! This is kind of off topic but I need some guidance from an established blog.

    Is it difficult to set up your own blog? I’m not very techincal but I can figure things out pretty fast.
    I’m thinking about making my own but I’m not sure where to start.

    Do you have any ideas or suggestions? Appreciate it

  5. Hi! Would you mind if I share your blog with my facebook
    group? There’s a lot of people that I think would really enjoy your content.
    Please let me know. Thank you

  6. you’re truly a just right webmaster. The web site loading speed
    is amazing. It sort of feels that you’re doing any distinctive trick.
    Also, The contents are masterpiece. you’ve performed a excellent job on this topic!

  7. Hi there, You’ve done an excellent job. I’ll definitely digg it
    and personally recommend to my friends. I am sure they’ll be benefited from this site.

  8. Hi colleagues, how is the whole thing, and what you want to say regarding this
    piece of writing, in my view its actually awesome designed for me.

  9. I relish, cause I discovered just what I
    used to be having a look for. You have ended my
    four day long hunt! God Bless you man. Have a nice day.

  10. I am really impressed with your writing skills as well as with the layout on your weblog.
    Is this a paid theme or did you customize it yourself? Either way keep up
    the excellent quality writing, it is rare to see a nice blog like this one these days.

Leave a Reply

Your email address will not be published.