Wednesday, April 26, 2006

Styling A Sitemap

I was recently thinking about sitemaps, since it so happens I have to design several for different sites I'm working on. In many cases a plain-old list (POL) works just fine as is, so long as each level of indentation is styled distinctly. But in other situations you want something just a little bit fancier, some graphics to jazz it up. I thought that this time it would be nice to use CSS on a plain-old list (POL), so that the markup would degrade nicely on problem systems. Here's a step-by-step tutorial explaining what I came up with.

Introduction


First I went looking for existing solutions. Alexander Sperl has a very nice tutorial, in which he shows how to make graphics that can be used on various list-style-image tags. Different levels of the sitemap tree are marked up with different classes, each one corresponding to a specific image.

There is one big problem with this method, namely that many different graphics (and corresponding list styles) are needed. His code handles 3 levels and requires 8 different images. His discussion of level four items is short: "that's something you can figure out for yourself." No wonder he doesn't want to tackle it; his method is not scalable. I want one that is.

There are three major parts to this exercise. We need to build the graphics files, design our stylesheets, and code the markup.

Our Goal


Let's take a closer look at the problem. Below is a screen capture of a typical nested list such as one might find in a sitemap. If you mouse over it you see the graphical version I want to build. Our objective in this will be to keep the underlying markup as close as possible to the original.




Inspection of the problem shows that the tree is made up of only four separate graphic elements. To see this for yourself, mouse over the graphic above, but this time press and hold the mouse button. I have marked the different graphical components vertically in the first section as 1, 2, 3, 4. Rather than build all possible combinations of graphics for as many levels of indentation as we may need, we'll just use these four graphics directly. And since one of them is empty we won't even bother with a graphic file for that. See? Simple!

The horizontal set of boxes shows how we need three sequential graphics for a third-level indent. The red boxes are margins we'll remember to add.

Basic HTML


Here follows the POL layout for the sitemap. I have indented freely so the structure is more obvious.
<p><b>Post-Punk And All That</b> [album version]</p>
<ul>
<li>Manchester
<ul>
<li>Magazine
<ul>
<li>Spiral Scratch</li>
<li>Real Life</li>
<li>Secondhand Daylight</li>
<li>The Correct Use of Soap</li>
</ul>
</li>
<li>Buzzcocks
<ul>
<li>Time's Up</li>
<li>Another Music in A Different Kitchen</li>
<li>Love Bites</li>
<li>A Different Kind Of Tension</li>
</ul>
</li>
<li>Joy Division
<ul>
<li>Unknown Pleasures</li>
<li>Closer</li>
<li>Still</li>
</ul>
</li>
</ul>
</li>
<li>Liverpool
<ul>
<li>OMD
<ul>
<li>OMD</li>
<li>Organisation</li>
</ul>
</li>
<li>Echo & the Bunnymen
<ul>
<li>Crocodiles</li>
<li>Heaven Up Here</li>
<li>Porcupine</li>
</ul>
</li>
</ul>
</li>
</ul>

Let's start the process of converting this simple code. To begin we will put a span classed as "sitemap" around this HTML, so that other CSS classes can be assigned relative to that. This prevents what we are doing here from affecting other parts of our markup. It also makes it easy to turn our effect on and off -- simply remove the outlying span.

Our CSS


We need to turn off the usual list formatting. This is a common first step in any list styling exercise. Thus the stylesheet begins with the following.
.sitemap ul, .sitemap li {
list-style-type: none;
margin: 0;
padding: 0;
}

In order to be able to freely use our three line graphics in any combination we need, I'm going to assign each one to a span element. Then, those spans can be used in place of the images themselves, giving us more flexibility in styling and better degradation.
.sitemap span.vert {background-image: url(map_vert.gif);}
.sitemap span.last {background-image: url(map_last.gif);}
.sitemap span.midd {background-image: url(map_midd.gif);}

The last part of the CSS works on each of those three spans, plus a fourth for that phantom blank element I referred to earlier. We style them to be the same height and width as the graphics themselves, and then add a margin to the left to ensure a nice offset. Since this is a typographic feature, I use ems, though the truth is this method is going to break down at other font sizes, since it would need graphics of different sizes as well. (That's also true of the original method.)

We need to ensure the background elements don't repeat. In order to get the spans acting as graphic segments we set them to display as blocks. Finally, we float them to the left so that each does not start a new line. Here's the finished CSS.
.sitemap span.none, .sitemap span.vert, .sitemap span.last, .sitemap span.midd {
width: 24px;
height: 18px;
margin-left: 1em;
background: transparent 0px 0px no-repeat;
display: block;
float: left;
}

For those wondering, I have kept the names of the graphics and the styles the same length (eg: "midd" instead of "mid") because this way the HTML code lines up better. No other reason!

Building Blocks


These four styles now act as graphical building blocks that we can drop into our HTML where we need them. The code looks quite verbose, but it's regular and hence a piece of cake to generate in the typical scenario of dynamic code. More importantly, it does not add any other structural information to the nested lists. Here's the complete HTML.
<span class="sitemap">
<p><b>Post-Punk And All That</b> [dub mix]</p>
<ul>
<li><span class="midd"></span>Manchester
<ul>
<li><span class="vert"></span><span class="midd"></span>Magazine
<ul>
<li><span class="vert"></span><span class="vert"></span><span class="midd"></span>Spiral Scratch</li>
<li><span class="vert"></span><span class="vert"></span><span class="midd"></span>Real Life</li>
<li><span class="vert"></span><span class="vert"></span><span class="midd"></span>Secondhand Daylight</li>
<li><span class="vert"></span><span class="vert"></span><span class="last"></span>The Correct Use of Soap</li>
</ul>
</li>
<li><span class="vert"></span><span class="midd"></span>Buzzcocks
<ul>
<li><span class="vert"></span><span class="vert"></span><span class="midd"></span>Time's Up</li>
<li><span class="vert"></span><span class="vert"></span><span class="midd"></span>Another Music in A Different Kitchen</li>
<li><span class="vert"></span><span class="vert"></span><span class="midd"></span>Love Bites</li>
<li><span class="vert"></span><span class="vert"></span><span class="last"></span>A Different Kind Of Tension</li>
</ul>
</li>
<li><span class="vert"></span><span class="last"></span>Joy Division
<ul>
<li><span class="vert"></span><span class="none"></span><span class="midd"></span>Unknown Pleasures</li>
<li><span class="vert"></span><span class="none"></span><span class="midd"></span>Closer</li>
<li><span class="vert"></span><span class="none"></span><span class="last"></span>Still</li>
</ul>
</li>
</ul>
</li>
<li><span class="last"></span>Liverpool
<ul>
<li><span class="none"></span><span class="midd"></span>OMD
<ul>
<li><span class="none"></span><span class="vert"></span><span class="midd"></span>OMD</li>
<li><span class="none"></span><span class="vert"></span><span class="last"></span>Organisation</li>
</ul>
</li>
<li><span class="none"></span><span class="last"></span>Echo & the Bunnymen
<ul>
<li><span class="none"></span><span class="none"></span><span class="midd"></span>Crocodiles</li>
<li><span class="none"></span><span class="none"></span><span class="midd"></span>Heaven Up Here</li>
<li><span class="none"></span><span class="none"></span><span class="last"></span>Porcupine</li>
</ul>
</li>
</ul>
</li>
</ul>
</span>

Conclusions


What's the score? Sperl styled 9 different areas and used 8 graphics to support a maximum of 3 nested levels. We've styled 4 spans and have used 3 (simpler) graphics to support an arbitrary number of levels. Furthermore, though I don't explore the options here, we have more flexibility in how to put together the graphics to form different types of maps. Finally, if we take away the outer span everything collapses back to the original look.

On the downside, this method does require additional spans in your code.

I am happy with that, but would love to hear from anyone who has further optimisations.

Resources


A sample file with all of the code is available for download as sitemap.html.

You will also need the graphics files. Save them to the same folder as the HTML via the usual right-click thingie.

vertical map graphic middle branch map graphic last branch map graphic

RELATED POSTS

4 comments:

Jan said...

Hey - thanks 4 that stylish style :-)

leif said...

Pretty nice but I'm not able to see the graphic files. My sidemap ist structured without dotted lines. Looks boring. The images are in the correct folder and the styles.css is made correctly. Even your sitemap.html is structured without dotted lines. My browser is mozilla and it doesn't work with IE.

robin said...

I just tested by right-clicking on each of the sitemap.html and the three GIF files, put them all in the same folder, and called up the HTML. Looks fine in FireFox and IE 6. Not sure what could be the problem, sorry.

Rob Hodgson said...

Simple, elegant solution, thank you.

Post a Comment