Ben Nadel's post about parsing CSS rules in ColdFusion reminded me of some of the techniques I've used in the past to make dynamic stylesheets. I've since stopped that practice, though, figuring that for my needs it didn't make sense to create a secondary CF request for the stylesheet each and every time someone called a page. So, I switched to a static stylesheet and used some of the techniques I've found from around the web. Save yourself some CPU cycles by letting the stylesheet and browser do the work instead.
Take, for example, the navigation at the top of my blog. The code for the navigation bar itself and the code for the stylesheet are the same for every page, yet the highlighted tab changes depending on which section of my site that you're in. The one thing that does change is the id attribute of the body tag. Read on how to get this technique to work for yourself.
To start creating self-selecting navigation tabs, start with an unordered list. Write out the list as regular HTML code and then use styles to convert it from the normal, vertically-oriented list into a horizontally-oriented one with background colors and borders.
The list code:
<body>
<ul id="nav">
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
<li><a href="/projects/">Projects</a></li>
</ul>
The styles:
#nav {position:absolute;top:0px;list-style:none;
height:27px;margin:0;padding:0;}
#nav li {display:inline;margin:0;padding:0;}
#nav li a {display:block;float:left;line-height:28px;color:#fff;
text-decoration:none; padding:0 1em;margin:0;
border-right:1px solid #fff;
background:#002FCC url(/tom/blog/images/nav_bg.gif) repeat-x 0 -24px;}
#nav li.home a {border-left:1px solid #fff;}
This will give you a nice horizontal bar, with each list item laid out on top of the bar. You may wonder why we have a special style for #nav li.home a; it's because all links have a white, single-pixel right-hand border, and to get a symmetrical look on the far left-hand side of the nav we need to specify one left-hand border on the first list element.
Now, how to give a different style to the tab you want to highlight? There are two things to do: first, add a dynamic id attribute to your body tag; and second, give each list item a unique class:
<body id="home"> <!-- Or blog, or projects -->
<ul id="nav">
<li class="home"><a href="/">Home</a></li>
<li class="blog"><a href="/blog/">Blog</a></li>
<li class="projects"><a href="/projects/">Projects</a></li>
</ul>
Then, we add one line to our styles specifying a slightly different style for the selected tab:
#home #nav .home a, #blog #nav .blog a, #projects #nav .projects a {
background-color:#002FCC;
background-image:none;
}
This new style line essentially reads like "...if you're a home-class tab in the home-id body, or you're a blog-class tab in a blog-id body, or you're a projects-class tab in a projects-id body, then you're selected." You can obviously add as many classes (better thought of as "sections") to this style line as you need.
So that's a simplified yet accurate view of how the navigation on this blog works. There are quite a few other ways to get what look like dynamic styles on your site with static stylesheets, and I'll go over those techniques in future posts. As I said, I used to do this kind of thing with ColdFusion or PHP, just writing out the nav dynamically and even writing the stylesheet as a dynamic file. But with this technique, you can save yourself some CPU cycles by letting the stylesheet and browser do the work instead.

Comments (2)
February 5, 2008
11:25AM | #
I used to do dynamic CSS for a project that needed it by making my stylesheet a .cfm
then I could add whatever variables inside the css file but you could just include it the same as any .css file.
February 5, 2008
11:30AM | #
@Brian; True, you can include static styles into a .cfm-based stylesheet if you really, really need to make it unique for the user... I just don't like the idea of creating an extra cf request for every page call. Given that most calls for your stylesheet will produce the same code, I generally think it's best to make it a static file. Otherwise, you're practically doubling the number of requests to the CF runtime for each pageview. That's a waste if you can do the same thing with a static stylesheet instead.