HOWTO: Style a Multi-Column List in HTML
For a project at work I was asked if I could lay out a long table-of-contents in our CMS as multiple columns. Logically enough, the table-of-contents renders as a flat, unordered list (UL) of list items (LI) … arranging that as multiple columns is a preposterous idea! Of course, preposterous questions can be very interesting.
So, we start with something like this:
<h1>Yadda Yadda</h1> <ul class="columns"> <li>BLAH blah blah one</li> <li>BLAH blah blah two</li> <li>BLAH blah blah three</li> <li>BLAH blah blah four</li> <li>BLAH blah blah five</li> <li>BLAH blah blah six</li> <li>BLAH blah blah seven</li> <li>BLAH blah blah eight really long example</li> <li>BLAH blah blah nine</li> <li>BLAH blah blah ten</li> <li>BLAH blah blah eleven</li> <li>BLAH blah blah twelve</li> </ul> <h1>Yappa Yappa</h1> |
Which renders as:
Yadda Yadda
- BLAH blah blah one
- BLAH blah blah two
- BLAH blah blah three
- BLAH blah blah four
- BLAH blah blah five
- BLAH blah blah six
- BLAH blah blah seven
- BLAH blah blah eight really long example
- BLAH blah blah nine
- BLAH blah blah ten
- BLAH blah blah eleven
- BLAH blah blah twelve
Yappa Yappa
Okay. So, multiple columns? That is what TABLE is for, but we are dealing with UL. But I have my old friend the float attribute, so I define a style sheet:
ul.columns li { list-style: none; float: left; width: 30%; } h1 { clear: left; } |
Now we render as three columns:
Yadda Yadda
- BLAH blah blah one
- BLAH blah blah two
- BLAH blah blah three
- BLAH blah blah four
- BLAH blah blah five
- BLAH blah blah six
- BLAH blah blah seven
- BLAH blah blah eight really long example
- BLAH blah blah nine
- BLAH blah blah ten
- BLAH blah blah eleven
- BLAH blah blah twelve
Yappa Yappa
Two columns? Four? Just tune the width attribute:
ul.columns li { list-style: none; float: left; width: 45%; } h1 { clear: left; } |
And you get:
- BLAH blah blah one
- BLAH blah blah two
- BLAH blah blah three
- BLAH blah blah four
- BLAH blah blah five
- BLAH blah blah six
- BLAH blah blah seven
- BLAH blah blah eight really long example
- BLAH blah blah nine
- BLAH blah blah ten
- BLAH blah blah eleven
- BLAH blah blah twelve
It is not perfect. The content renders left-to-right, so strictly speaking, these aren’t columns.
If you narrow enough to cause wrapping you get some odd gaps.
Due to margins and the like, you can’t just say three columns is 33%, two columns is 50% . . . if you narrow this page enough you’ll see a graceful degradation from more columns to fewer.
Here’s a more dynamic example, where wider pages will get more columns:
ul.columns li { list-style: none; float: left; width: 15em; } h1 { clear: left; } |
Renders as:
- BLAH blah blah one
- BLAH blah blah two
- BLAH blah blah three
- BLAH blah blah four
- BLAH blah blah five
- BLAH blah blah six
- BLAH blah blah seven
- BLAH blah blah eight really long example
- BLAH blah blah nine
- BLAH blah blah ten
- BLAH blah blah eleven
- BLAH blah blah twelve
The block following your UL will need to clear the floated content, hence the clear: left
on the H1, above.
See also:
- http://dannyman.toldme.com/scratch/li-column.html — my “scratch pad” for this specific question.
- http://dannyman.toldme.com/scratch/columns.html — some related experimentation I did in 2003.