List columns and item images

Suppose you have a list (ul or ol) that contains many short items which takes up a lot of vertical space and generates much horizontal whitespace:

Depending on the data and design of the containing document styling the list in columns might be approciate.

Basic Columns

One way to columnize the list is to float the list items and assigning a concrete width to it.

Two Columns

ul.columns li { float: left; width: 50%; }

Three Columns

ul.three li { float: left; width: 33%; }

Four Columns

ul.four li { float: left; width: 25%; }

Adding images to the items

Now that the list is columnize, one might want to spice up the thing with images for the individual items. Because background image positions can be better controlled; we use them instead of list-style-image. The list items then need a bit of padding to avoid that the text covers the icons.

The Problem

The CSS2 box model formula to calculate the width of an element looks like this: element width = width + padding + border The problem with this formula is that we cannot set the width to a percentage value and use a non-percent value for the padding, i.e. control the maximum width in a across all browsers — this is the reason against max-width

The Solution

One possible solution is to wrap the list items in another tag, e.g. span to apply the padding to — the items may already be wrapped in a tag, e.g. the origin for the technique described in this document is a list of links so you might not need to add a wrapper element.

Samples

Using the solution on the sample data yields the following CSS:

  1. ul.columns li {
  2. float: left;
  3. width: 50%;
  4. }
  5. ul.three li {
  6. width: 33%;
  7. }
  8. ul.four li {
  9. width: 25%;
  10. }
  11. ul.iconified li span {
  12. background: #FFF url(icon.gif) no-repeat scroll top left;
  13. padding-left: 24px;
  14. }

Two Columns

<ul class="columns iconified">

Three Columns

<ul class="columns three iconified">

Four Columns

<ul class="columns four iconified">

Preserving the top-bottom, left-right Order

The columns would look nicer if they had a top-bottom, left-right order instead of the current left-right, top-bottom one. Possible solutions for this include:

The drawback of these solutions is that the separation of content and style is ruined and a new design needs adjustments on the server (which is bad when you provide different skins).

With a little help from JavaScript

With these drawbacks in mind a JavaScript script to reorder the list items is a better choice.

Limitations

The provided columnizeItemOrder function has the following limitations:

How to use the script

Include the JavaScript file columnize.js in your page and execute columnizeItemOrder(<list id>, <number of columns>); for each column list.

Samples

The head for these samples:

  1. <script type="text/javascript" src="columnize.js"></script>
  2. <style type="text/css"">
  3. ul.columns li {
  4. float: left;
  5. width: 50%;
  6. }
  7. ul.three li {
  8. width: 33%;
  9. }
  10. ul.four li {
  11. width: 25%;
  12. }
  13. ul.iconified li span {
  14. background: #FFF url(icon.gif) no-repeat scroll top left;
  15. padding-left: 24px;
  16. }
  17. </style>
Two Columns
columnizeItemOrder("list2", 2);
Three Columns
columnizeItemOrder("list3", 3);
Four Columns
columnizeItemOrder("list4", 4);
Five Columns
columnizeItemOrder("list5", 5);