CSS Table of Contents

I've been working on a design for a mini-site lately that has a gothic and worn sort of aesthetic, and needed a navigation style to fit with the theme. I decided to go with a look that resembled a book-style table of contents, with the page name on the left and dots aligning to the corresponding page on the far right. As I often do, I knew I had designed myself into a future css headache, but decided I was up for the challenge when the time came.

The Goal

screenshot of css table of contents

Making A Simple Task Difficult

I suppose any sane developer would simply make an unordered list and script the numbering using javascript or some backend lingo, but being the CSS masochist that I am, I wanted to develop this navigation using the native numbers that a browser renders in an ordered list. This would mean flipping the ordered list so that the numbers aligned to the right, requiring some tricky negative margins and fixed widths. Aside from my apparent drive to make simple print design tasks more difficult with CSS, I figured this would at least provide an opportunity to write another post in my process blog... and here I am.

Short-Lived Success

Much to my surprise, the styling went quickly, rendering as I'd hoped in most browsers after very little fuss. One span was required for blotting out the dotted border just beneath the page names with a solid fill. The trouble came, of course, with Internet Exploder (6 and 7), which once again ruined my fun by numbering all of my list items as "01". A thorough search for info on this obscure bug led me to an article on Quirksmode which basically described that setting a width on ordered list elements will make IE render all numbered list items as if it is the first list item. Since my solution required a width on the OL, I was going to need to find a work-around.

Professional IE CSS debugging

Unfortunately, at the time I could find no work-around for the issue, so I did what any web standardizer does with nonsensical IE bugs - I started throwing things at it in frustration. Hmm, how about "position: relative;" or "height: 1%;"... those usually work... nope - not this time. By pure chance, After spending far too much time on it, I realized that explicitly setting "display: list-item;" on the LI's would result in proper numbering. I'm not sure what cryptic display property IE was formerly using to display list items, but regardless, I had a working solution.

Code Examples

The following shows the html, css and a link to a demo page for a scalable CSS-driven table of contents navigation. In the off chance you need such a thing in your projects, feel free to use it.

HTML: An Ordered List containing an anchor and one span.

<ol>
    <li><a href="#"><span>Page One</span></a></li>
    <li><a href="#"><span>Page Two</span></a></li>
    <li><a href="#"><span>Page Three</span></a></li>
    <li><a href="#"><span>Page Four</span></a></li>
    <li><a href="#"><span>Page Five</span></a></li>
</ol>

CSS

body{
    font-family: Georgia, sans-serif;
}
ol {
    text-align: right;
    list-style-type: decimal-leading-zero;
    width: 0;
}
li {
    margin: 0 0 2em 30em;
    text-align: left;
    list-style-type: decimal-leading-zero;
    width: 1em;
    display: list-item;
}
li span {
    background: #fff;
    position: relative;
    top: .2em;
    padding-right: 1em;
}
li a {
    position: relative;
    top: -.2em;
    margin-left: -30em;
    display: block;
    color: #222;
    border-bottom: 2px dotted #aaa;
    width: 27.5em;
}
li a:hover {
    color: red;
    border-bottom: 2px dotted red;
}

Demo Page