[css] Is there a way to break a list into columns?

My webpage has a 'skinny' list: for example, a list of 100 items of one word in length each. To reduce scrolling, I want to present this list in two or even four columns on the page. How should I do this with CSS?

_x000D_
_x000D_
<ul>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
</ul>
_x000D_
_x000D_
_x000D_

I prefer the solution to be flexible so that if the list grows to 200 items, I don't have to do a lot of manual adjustments to accommodate the new list.

This question is related to css html-lists

The answer is


I've found that (currently) Chrome (Version 52.0.2743.116 m) has tons of quirks and issues with css column-count regarding overflow items and absolute positioned elements inside items, especially with some dimensions transitions..

it's a total mess and cannot be fix, so I tried tackling this through simple javascript, and had created a library which does that - https://github.com/yairEO/listBreaker

Demo page


This answer doesn't necessarily scale but only requires minor adjustments as the list grows. Semantically it might seem a little counter-intuitive since it is two lists, but aside from that it'll look the way you want in any browser ever made.

_x000D_
_x000D_
ul {_x000D_
  float: left;_x000D_
}_x000D_
_x000D_
ul > li {_x000D_
  width: 6em;_x000D_
}
_x000D_
<!-- Column 1 -->_x000D_
<ul>_x000D_
  <li>Item 1</li>_x000D_
  <li>Item 2</li>_x000D_
  <li>Item 3</li>_x000D_
</ul>_x000D_
<!-- Column 2 -->_x000D_
<ul>_x000D_
  <li>Item 4</li>_x000D_
  <li>Item 5</li>_x000D_
  <li>Item 6</li>_x000D_
</ul>
_x000D_
_x000D_
_x000D_


Here is what I did

_x000D_
_x000D_
ul {_x000D_
      display: block;_x000D_
      width: 100%;_x000D_
}_x000D_
_x000D_
ul li{_x000D_
    display: block;_x000D_
    min-width: calc(30% - 10px);_x000D_
    float: left;_x000D_
}_x000D_
_x000D_
ul li:nth-child(2n + 1){_x000D_
    clear: left;_x000D_
}
_x000D_
<ul>_x000D_
  <li>1</li>_x000D_
  <li>2</li>_x000D_
  <li>3</li>_x000D_
  <li>4</li>_x000D_
  <li>5</li>_x000D_
  <li>6</li>_x000D_
  <li>7</li>_x000D_
  <li>8</li>_x000D_
  <li>9</li>_x000D_
  <li>0</li>_x000D_
</ul>
_x000D_
_x000D_
_x000D_


2021 - keep it simple, use CSS Grid

Lots of these answers are outdated, it's 2020 and we shouldn't be enabling people who are still using IE9. It's way more simple to just use CSS grid.

The code is very simple, and you can easily adjust how many columns there are using the grid-template-columns. See this and then play around with this fiddle to fit your needs.

_x000D_
_x000D_
.grid-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}
_x000D_
<ul class="grid-list">
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
</ul>
_x000D_
_x000D_
_x000D_


If you want a preset number of columns, you can use column-count and column-gap, as mentioned above.

However, if you want a single column with limited height that would break into more columns if needed, this can be achieved quite simply by changing display to flex.

This will not work on IE9 and some other old browsers. You can check support on Can I use

_x000D_
_x000D_
<style>_x000D_
  ul {_x000D_
    display: -ms-flexbox;           /* IE 10 */_x000D_
    display: -webkit-flex;          /* Safari 6.1+. iOS 7.1+ */_x000D_
    display: flex;_x000D_
    -webkit-flex-flow: wrap column; /* Safari 6.1+ */_x000D_
    flex-flow: wrap column;_x000D_
    max-height: 150px;              /* Limit height to whatever you need */_x000D_
  }_x000D_
</style>_x000D_
_x000D_
<ul>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
    <li>Item</li>_x000D_
</ul>
_x000D_
_x000D_
_x000D_


The mobile-first way is to use CSS Columns to create an experience for smaller screens then use Media Queries to increase the number of columns at each of your layout's defined breakpoints.

_x000D_
_x000D_
ul {_x000D_
  column-count: 2;_x000D_
  column-gap: 2rem;_x000D_
}_x000D_
@media screen and (min-width: 768px)) {_x000D_
  ul {_x000D_
    column-count: 3;_x000D_
    column-gap: 5rem;_x000D_
  }_x000D_
}
_x000D_
<ul>_x000D_
  <li>Item</li>_x000D_
  <li>Item</li>_x000D_
  <li>Item</li>_x000D_
  <li>Item</li>_x000D_
  <li>Item</li>_x000D_
  <li>Item</li>_x000D_
  <li>Item</li>_x000D_
  <li>Item</li>_x000D_
  <li>Item</li>_x000D_
  <li>Item</li>_x000D_
</ul>
_x000D_
_x000D_
_x000D_


If you can support it CSS Grid is probably the cleanest way for making a one-dimensional list into a two column layout with responsive interiors.

_x000D_
_x000D_
ul {_x000D_
  max-width: 400px;_x000D_
  display: grid;_x000D_
  grid-template-columns: 50% 50%;_x000D_
  padding-left: 0;_x000D_
  border: 1px solid blue;_x000D_
}_x000D_
_x000D_
li {_x000D_
  list-style: inside;_x000D_
  border: 1px dashed red;_x000D_
  padding: 10px;_x000D_
}
_x000D_
<ul>_x000D_
  <li>1</li>_x000D_
  <li>2</li>_x000D_
  <li>3</li>_x000D_
  <li>4</li>_x000D_
  <li>5</li>_x000D_
  <li>6</li>_x000D_
  <li>7</li>_x000D_
  <li>8</li>_x000D_
  <li>9</li>_x000D_
<ul>
_x000D_
_x000D_
_x000D_

These are the two key lines which will give you your 2 column layout

display: grid;
grid-template-columns: 50% 50%;

If you are looking for a solution that works in IE as well, you could float the list elements to the left. However, this will result in a list that snakes around, like this:

item 1 | item 2 | item 3
item 4 | item 5

Instead of neat columns, like:

item 1 | item 4
item 2 | 
item 3 | 

The code to do that would be:

ul li {
  width:10em;
  float:left;
}

You could add a border-bottom to the lis to make the flow of the items from left to right more apparent.