Is there a way to break a list into columns?
CssHtml ListsCss Problem Overview
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?
<ul>
<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>
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.
Css Solutions
Solution 1 - Css
The CSS solution is: http://www.w3.org/TR/css3-multicol/
The browser support is exactly what you'd expect..
It works "everywhere" except Internet Explorer 9 or older: http://caniuse.com/multicolumn
ul {
-moz-column-count: 4;
-moz-column-gap: 20px;
-webkit-column-count: 4;
-webkit-column-gap: 20px;
column-count: 4;
column-gap: 20px;
}
See: http://jsfiddle.net/pdExf/
If IE support is required, you'll have to use JavaScript, for example:
http://welcome.totheinter.net/columnizer-jquery-plugin/
Another solution is to fallback to normal float: left
for only IE. The order will be wrong, but at least it will look similar:
See: http://jsfiddle.net/NJ4Hw/
<!--[if lt IE 10]>
<style>
li {
width: 25%;
float: left
}
</style>
<![endif]-->
You could apply that fallback with Modernizr if you're already using it.
Solution 2 - Css
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 li
s to make the flow of the items from left to right more apparent.
Solution 3 - Css
grid
or column-count
It's 2022 - keep it simple, use CSS Lots of these answers are outdated, it's 2021 and we shouldn't be enabling people who are still using IE9. It's way more simple to just use CSS grid or column-count
.
The code is very simple, and you can easily adjust how many columns there are using grid-template-columns
or column-count
.
grid
solution:
.grid-list {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
<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>
column-count
solution that maintains order:
.column-list {
column-count: 4;
}
<ul class="column-list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
<li>item 6</li>
<li>item 7</li>
<li>item 8</li>
<li>item 9</li>
<li>item 10</li>
<li>item 11</li>
<li>item 12</li>
</ul>
Solution 4 - Css
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
<style>
ul {
display: flex;
flex-flow: wrap column;
max-height: 150px; /* Limit height to whatever you need */
}
</style>
<ul>
<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>
Solution 5 - Css
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.
ul {
float: left;
}
ul > li {
width: 6em;
}
<!-- Column 1 -->
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<!-- Column 2 -->
<ul>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
Solution 6 - Css
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.
ul {
column-count: 2;
column-gap: 2rem;
}
@media screen and (min-width: 768px)) {
ul {
column-count: 3;
column-gap: 5rem;
}
}
<ul>
<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>
Solution 7 - Css
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
Solution 8 - Css
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.
ul {
max-width: 400px;
display: grid;
grid-template-columns: 50% 50%;
padding-left: 0;
border: 1px solid blue;
}
li {
list-style: inside;
border: 1px dashed red;
padding: 10px;
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<ul>
These are the two key lines which will give you your 2 column layout
display: grid;
grid-template-columns: 50% 50%;
Solution 9 - Css
Here is what I did
ul {
display: block;
width: 100%;
}
ul li{
display: block;
min-width: calc(30% - 10px);
float: left;
}
ul li:nth-child(2n + 1){
clear: left;
}
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>0</li>
</ul>