Style Sheet Organization

As much as I like having CSS in my toolbox to provide separation of presentation from content, I often find myself hating that I have to use it in order to provide maintainable sites. Part of that is due to the fact that it can be difficult. Language limitations and cross-browser variances often force a lot of time to be spent dealing with minutia that, if there were any justice in this world, would be easier than it is. Truthfully, though, I’m over that. Maybe I’m just jaded after so many years of doing the dance. My bigger issue is the maintainability of style sheets.

As a general rule, I place a high priority on accessibility, readability and maintainability in any code I write or have to answer for. CSS makes that a very, very difficult dream to achieve. When used properly, which is to say exclusively (as far as I’m concerned), style sheet rules are all maintained externally. No inline styles, no embedded style sheets.

Over the years, I’ve tried countless organization techniques. Some of those were techniques espoused by others, some were techniques espoused by others that I bastardized to meet my own needs and still others are mine alone (as far as I know), but in the end I’ve developed a “system” that works pretty well for me. It’s hardly perfect – the nature of CSS doesn’t lend itself to organizational perfection – but it’s a reasonable enough approximation, I think, until or unless the language specification itself improves.

Employ Multiple Source Files

I’ll start with the obvious because, well, it’s obvious. Don’t try to style an entire project with a single style sheet. For small, static projects this may suffice, but it will not scale. It’s more maintainable to start with multiple small files even if it seems like overkill. My projects include at least three style sheets: a reset style sheet, a universal style sheet and a page-level style sheet.

Reset Style Sheet

The first style sheet I create for each project is a reset style sheet (_reset.css). The rules in this style sheet exist solely to negate default styles that are often implemented differently across browsers. I tend to use Eric Meyer’s version because, well, he’s Eric Meyer, you know? The guy’s put a lot of thought into these things.

Another popular technique is to apply the universal selector.

* { margin: 0; padding: 0; ... }

That’s just too generic for my tastes. A good reset style sheet, whether Eric’s or a home grown version, should include some thought and have some logic behind what’s being reset.

A Global Style Sheet

The next file I create is a global style sheet (_global.css). The global style sheet includes all of my generic rules. These are the rules that are applied by default and will be used in 95% of the applicable situations. For example, my reset style sheet may force emphasized text to a normal (non-italicized) style, but I like the italicized styling provided by most browsers. In my global style sheet, I’ll set my preferred style.

em { font-style: italics; }

Similarly, this is where I set rules for my typical link colors, my document background and font, etc.

If anyone’s wondering why I prefix the file names listed above with underscores, it’s because the reset and global style sheets are universally applicable to every page in the site. The underscore keeps these files at the top of the directory listing so they can be accessed quicker. The remaining file names are consistent with their content and it makes more sense to think of them that way. The reset and global files are the only ones that I consider “special”.

Structural Style Sheets

I’ve read about many ways to catalog additional style sheets applied on top of the reset and global style sheets and I think I’ve tried every single one of them at one time or another. One of the most espoused methods is to create style libraries. For example, typography.css for text styles, layout.css for box model styles, etc. There are two key reasons that I abandoned this technique rather quickly:

  1. Using the method, selectors are inevitably repeated – often in each library file. If one of those selectors changes, maybe because an element’s ID value had to be changed, then each library file has to be edited.
  2. I typically find myself styling one element at a time, and then several elements within the same primary structural group. I rarely find myself editing just the typography of multiple elements. Because of my workflow, this method usually left me opening multiple files just to update a heading, for example.

Instead, I create a style sheet for each primary structural element. In a “typical” site design, that might mean header.css, footer.css, sidebar.css, content.css, etc. Those components are pretty typical and rarely change (although it is conceivable that they’ll do so) so I feel pretty safe with that kind of breakdown. With this organizational method, I can spend all day long tweaking the look of my footer and never open more than one style sheet.

Link Source Files Properly

As soon as multiple files are employed, care has to be taken to ensure that the “cascading” aspect of CSS is managed properly. Using this method, the reset style sheet creates the baseline, the global style sheet provides the foundation and everything else builds from there. Each layer in the stack should be able to override those layers beneath it, but not those above. My linked style sheet stack looks something like this:

<link type="text/css" rel="stylesheet" href="/resources/css/_reset.css" /> <link type="text/css" rel="stylesheet" href="/resources/css/_global.css" /> <link type="text/css" rel="stylesheet" href="/resources/css/header.css" /> <link type="text/css" rel="stylesheet" href="/resources/css/footer.css" /> <link type="text/css" rel="stylesheet" href="/resources/css/sidebar.css" /> <link type="text/css" rel="stylesheet" href="/resources/css/content.css" />

The last four, of course, are variable depending on the structure that best fits the document.

Order, Group & Indent Rules

To be clear, I’m not talking about grouping selectors (yet). The focus here is on grouping rules. Using the header of this site as an example, my header.css style sheet would style every element above the body (the “body” begins where the white background begins). The header includes its own functional groupings: the site title bar, the navigation bar and the info bar (just the names I gave them here to distinguish one from the other). Given those secondary groups, the header.css style sheet might be organized like this:

#header {
   #header #titlebar {
      #header #titlebar h1 {
      #header #titlebar ul {
         #header #titlebar ul li {
   #header #subtitlebar {
      #header #subtitlebar ul {
         #header #subtitlebar ul li {
   #header #info {
   /** ...and so on... */

Using this technique, I’ve found that I don’t have a need for the section flags I’ve seen others use to help them tag sections of their style sheets. White space and semantic ID values do that for me.

Prefer Descendant Selectors

I’ve found that if I organize my markup well, I have a very limited need for classes and, to a lesser degree, IDs in that markup. I use IDs to identify the top level element of any block whose child elements I need to access uniquely. Classes are thrown in when I need the same style for multiple, completely unrelated or disparate elements. For example, I’ll usually have a .clear-float class because lots of elements need to be cleared and they’re all over the place.

One Declaration per Line

Just imagine an entire style sheet filled with rules that look like this:

div#sign_in {height: 130px; overflow: hidden; display: block; ... } div#sign_in h1 {background: transparent url("../images/sign_in.gif") no-repeat; ... } div#sign_in form {margin: 0; padding: 0; ... } div#sign_in form fieldset {display: block; clear: both; padding: 0 15px 0 15px; ... } div#sign_in form label {font-weight: bold; display: block; float: left; font-size: 12px; ... } div#sign_in form input {float: right; width: 150px; font-size: 12px; margin-bottom: 10px;} div#sign_in .submit {height: 20px; float: right; clear: both; width: auto; ... } div#sign_in input.submit_enter, div#sign_up input.submit_enter {position: absolute ... }

Ugh. Now that it’s been imagined…purge the very memory. Compact style sheets to preserve bandwidth as required, but do it at build time and always preserve a nicely formatted source file as the working copy.

Alphabetize properties

I can never remember exactly which properties fit into which “standard” CSS grouping. I also think some of them are more ambiguous that they should be for organizing selectors, so I stick to alphabetical order. “A” to “Z” is reasonably well known, has a better than average adoption rate, is quite unambiguous and its sequencing probably isn’t going to change any time soon. As with many standards, though, it probably doesn’t matter which one you choose as long as you do choose and stick to one.

Group Selectors with Caution

Grouping selectors is a powerful tool for eliminating redundancy and, as a result, bandwidth consumption, but I caution against over optimization. The complete elimination of redundancy leads to some pretty obscure groups that will be ridiculously difficult to track down a year or two from now. Favor readability over performance.

Instead, be very selective about grouping. Group only if the selectors being groups are tightly related in some way and whose changes are likely to be coupled going forward.

Use the Proper Syntax

Sometimes the correct syntax isn’t strictly necessary. For example, the last declaration in a declaration block isn’t required to end with a semicolon. Put one there anyway. You never know when another declaration will need to be added after it and suddenly that “optional” semicolon is required. It’s easy to forget that it’s not there.

Subscribe3 Comments on Style Sheet Organization

  1. Chad said...

    I usually keep global and structural together, just keep ‘em separated within the single file.

    The two sheets you’re missing, IMHO, are a “fix-ie” style sheet and print styles. If I’ve done well with my global styles, the fix-ie version has less than ten declarations. The fix-ie keeps hacks separate and manageable and is called with a conditional comment.

    Far too many sites with great content are killing too many trees. I don’t need the site menu or that monster banner when I’m printing a procedure. I try not to print often, and I always print double-sided pages, and it just ain’t that much more work to add a ‘display: none’ to screen elements that have no business being seen on paper.

  2. Rob Wilkerson said...

    Right on, Chad. IE styles are definitely missing. I considered including that, but ended up deciding against it for two reasons:

    1. The post intended to focus on style sheet organization rather than the browser incompatibilities and I felt like adding IE-centric style sheets would blur that distinction.
    2. Like you, if I do things right, I can often get away without using IE-specific styles.

    That said, they are usually a necessary evil. When I need them, I tow a pretty hard line about keeping them external themselves and including them with conditional comments. I choose this path because I always know why a rule was included if it’s in an IE file and I can easily remove any “hacks” when/if I decide I don’t want them any more. I’ll usually create an IE7 sheet first and then create an IE6 version if things still aren’t right.

    I’ll admit, though, that I’m horrible about print style sheets. Unless specifically requested, all too often I’ll do everything I can to avoid creating them. I’m not proud of that – you’re right that it’s not all that hard – but in the interest of full disclosure, I give you my admission of failure. :-)

  3. Chad Kieffer said...

    Ha! Yes, I am the high and mighty print stylist. Just don’t view source on my sites :)