Some problems just never go away… especially where CSS3 multi-columns are concerned

Note: This post has been updated.

I don’t use CSS3 multi-columns (based around the column-count and column-gap properties) very much, mainly because a) I don’t need columns in my layouts very often and b) usually when I do need columns, this method is inadequately flexible for what I’m trying to accomplish.

Today I have a good use case though. A simple (but long) list of links, that I want to display as 3 columns on wide screens, 2 columns on tablets and a single column on phones. Great, except when I got it working, I found that — in Chrome only, which is a bit odd — the top of the first column is higher than the rest. It looks fine in Safari and Firefox.

I googled, as always, for a solution, and found several suggestions that seemed like they should work, and people claimed they did work, but for me, they didn’t. Then I found this comment on a post on the topic, and decided to try the column-break-inside property, which is something I normally only use in print CSS.

It still didn’t work. But then, vendor prefix to the rescue! I needed the -webkit prefix, and it worked. This needs to be applied to the elements inside your column container, not the container itself. Here’s my full CSS block:

.columns {
  -moz-column-count: 3;
  -webkit-column-count: 3;
  column-count: 3;
  -moz-column-gap: 3em;
  -webkit-column-gap: 3em;
  column-gap: 3em;
}

/* Fix for unbalanced top alignment in Chrome */
.columns > * {
  -webkit-column-break-inside: avoid;
  column-break-inside: avoid;
}

You’ll also want to repeat the .columns section (or its equivalent for your class/element names) in your media queries, changing column-count appropriately where you want to collapse down to fewer columns.

Since other solutions worked for other people, I’m guessing my solution might not work for everyone either. But I hope it helps someone… maybe you!

Update (6/28/2017)

This problem really does never go away. And I’ve just run into a situation where the above fix doesn’t work. This is only affecting Safari — I think Chrome has actually fixed the bug. But some trial and error led to this new solution that fixes the problem in Safari as well.

/* New fix for Safari */
.columns > * {
  display: inline-block;
  width: 100%;
}

I’m still not totally sure why display: inline-block; is the magic bullet for column alignment issues, but it works. Adding width: 100%; is what keeps these inline blocks from actually appearing on the same line, if they’re short enough. (Also note that I removed the column-break-inside stuff… don’t seem to need it with this change.)

Update (6/12/2020)

Wow… it really never goes away, does it?

Now I’ve found that if I am applying my .columns class to a <ul> tag, its <li> tags lose their bullets, because they apparently need to have display: list-item (or have it implied). When did display: list-item get added to the CSS spec anyway? I’d swear it didn’t even exist when I was first working on this issue, but I’m an old fart now and time has lost all meaning.

Anyway… I did manage to figure out a workaround to this. So add the following after the update above (which you’ll still keep):

/* New fix for Safari */
.columns > li {
  display: list-item;
  margin: 0 !important; /* Maybe you won’t need !important */
  padding-bottom: 0.5em; /* Add some padding to make up for any margin you’re losing above */
}