Columnize

A Javascript function to take a list, unordered or ordered, and set its list items to specified columns.

HTML

<p>This is just a simple list to show the concept.</p>

<ol id="list1">
    <ol>one</ol>
    <li>two</li>
    <li>three</li>
    <li>four</li>
    <li>five</li>
    <li>six</li>
    <li>seven</li>
    <li>eight</li>
    <li>nine</li>
    <li>ten</li>
</ol>

<p>Slightly more complex list with paddings and margins involved. Plus links that are styled as buttons.</p>

<ol id="list2">
    <li><a href="#">one</a></li>
    <li><a href="#">two</a></li>
    <li><a href="#">three</a></li>
    <li><a href="#">four</a></li>
    <li><a href="#">five</a></li>
    <li><a href="#">six</a></li>
    <li><a href="#">seven</a></li>
    <li><a href="#">eight</a></li>
    <li><a href="#">nine</a></li>
    <li><a href="#">ten</a></li>
</ol>

<p>IE7 has slight issues with all this, especially if you display the bullets. Seems to run fine in most browsers.</p>

CSS

p {
    margin: 10px auto;
    width: 500px;
}

#list1 {
    border: 1px solid black;
    margin: 10px auto;
    padding: 10px;
    width: 500px;
}

#list2 {
    margin: 10px auto;
    padding: 10px;
    width: 500px;
}
#list2 li {
    width: 200px;
}
#list2 a {
    background: #1e5799;
    background: -moz-linear-gradient(top,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%);
    background: -ms-linear-gradient(top,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%);
    background: -o-linear-gradient(top,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%);
    background: -webkit-linear-gradient(top,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%);
    background: linear-gradient(top,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%);
    color: white;
    display: inline-block;
    height: 30px;
    line-height: 30px;
    margin: 4px;
    text-align: center;
    text-decoration: none;
    width: 100%;
}
#list2 a:hover {
    background: #c9de96;
    background: -moz-linear-gradient(top,  #c9de96 0%, #8ab66b 44%, #398235 100%);
    background: -ms-linear-gradient(top,  #c9de96 0%, #8ab66b 44%, #398235 100%);
    background: -o-linear-gradient(top,  #c9de96 0%, #8ab66b 44%, #398235 100%);
    background: -webkit-linear-gradient(top,  #c9de96 0%, #8ab66b 44%, #398235 100%);
    background: linear-gradient(top,  #c9de96 0%, #8ab66b 44%, #398235 100%);
}

JavaScript

function columnize(list, columnNumber, columnWidth) {
    // how many list items per column
    // try to make them equal as possible
    var itemsNumber = Math.ceil(list.children("li").length / columnNumber);
    // get the reported height of the list items
    var itemsHeight = parseInt(list.children("li").height(), 10);
    // enforce the reported height, you'd be surprised
    list.children("li").height(itemsHeight);
    // get the top margin height of list items
    var itemsMarginHeight = parseInt(list.children("li").css("margin-top"), 10);
    // get top and bottom padding of list items
    var itemsPaddingHeight = parseInt(list.children("li").css("padding-top"), 10) + parseInt(list.children("li").css("padding-bottom"), 10);
    // determine what the height of columns should be
    var itemsColumnHeight = (itemsHeight + itemsMarginHeight) * itemsNumber;
    // just a simple count variable for later use
    var count = 1;
    
    // go through each list item to set position as needed
    list.children("li").each(function(i) {
        // find first list item in each column
        // adjust margin-top to push it to line up with top
        if (i === itemsNumber * count) {
            $(this).css("margin-top", -itemsColumnHeight);
        }
        // increase the count as needed
        if (i > itemsNumber * count - 1) {
            count++;
        }
        // move each new column to right the required distance
        $(this).css("margin-left", columnWidth * count - columnWidth);
    });
    
    // adjust height of containing list as needed
    // sometimes this is needed for some browsers
    // doesn't hurt to do it anyway
    list.css("height", itemsColumnHeight);
}

// call function to set our list to have columns
// columnize(list id, number of columns, width of columns);
columnize($("#list1"), 3, 200);
columnize($("#list2"), 2, 250);