November 29, 2006
The Best Way to Organize A Stylesheet
The title of this article is meant facetiously. There is no best way to organize anything; the value and suitability of any organizational method is entirely subjective. What follows, then, is one solution-in-process to the challenges of organizing a stylesheet, honed during five years of building CSS-based websites.
The Perfect Stylesheet
Like the perfect mate, the perfect stylesheet is a mirage, a chimera. There are technical reasons for this, which I'll address shortly, but for now I'd like to define the perfect stylesheet's key characteristics, as these help determine my organizational approach.
The perfect stylesheet should be:
- Easy to write, adhering to a logical and intuitive structure
- Easy to use, with rules that are simple to find, understand, and change, and with no surprises due to unexpected or misunderstood inheritance
#1 is attainable; #2 is not—or not completely. Dave Shea has shown why by identifying two contrasting CSS authoring techniques: one based on "dependency"; the other, "redundancy." Dave explains this better than I could, but in brief, he's referring to greater or lesser reliance on inheritance in CSS rules.
To give a simple example, here are two approaches that yield the same result:
Greater dependency:
h2 {color: #000; margin: .25em 0 1em;}
h2.highlight {color: #ff0;}
Greater redundancy:
h2 {color: 000; margin: .25em 0 1em; }
h2.highlight {color: #ff0; margin: .25em 0 1em;}
In the first example, the more specific rule, h2.highlight, doesn't include the margin declaration, since those styles will be inherited from the h2 rule. In the second example, h2.highlight includes the redundant declaration.
As presented, the redundancy of the second example seems unnecessary. However, there are cases in which this approach makes sense; for example, when two rules appear in different parts of a lengthy stylesheet (or in two different stylesheets), or when updates will handled by a non-expert or someone unfamiliar with the stylesheet.
In general, redundancy makes it easier to change individual rules but more difficult to change multiple rules. Returning to the examples above, imagine that you want to change the bottom margin of all h2's on the site from 1em to .5em. In the dependency example, this would require a single change:
h2 (color: #000; margin: .25em 0 .5em;}
However, the redundancy example would require changes to multiple rules:
h2 {color: 000; margin: 25em 0 .5em;}
h2.highlight {color: #ff0; margin: 25em 0 .5em;}
While this example may make multiple changes seem simple, they can become more challenging when the relevant rules appear in different parts of the stylesheet, or in multiple stylesheets, or when more than two rules are involved. Further, it can be difficult to determine how many rules need to be changed, particularly if one is a non-expert or unfamiliar with the stylesheet.
My point is that neither dependency nor redundancy is a perfect approach, and that, more broadly, there can be no perfect stylesheet, one that incorporates the advantages of both approaches.
This said, expert authors tend to favor dependency over redundancy, as this approach produces leaner, simpler stylesheets (simpler, I should add, to an expert). Personally, I avoid redundancy altogether. This is partly an aesthetic preference and partly a tactic for making stylesheets easier to edit. The key is consistency. Since I'm consistent in avoiding redundancy, I know that every declaration encountered while editing is necessary for that particular rule, either to establish a style or override one or more inherited styles. Along similar lines, I'm careful to structure each stylesheet so as to best leverage the power of inheritance and avoid its pitfalls. More on this shortly.
Recommendations Toward the Perfect Stylesheet
In the following examples, I use the Luminous stylesheet as my model; however, I could have used any recent stylesheet I've written, since all follow the same structure and incorporate the same techniques. This may be the most significant recommendation I have to offer: Using the same approach across projects reduces development time on each, as one always knows where to place specific rules, where to find them later, and where to look when facing problems. Expert authors are consistent.
Include a Header
I'm always surprised when I encounter a stylesheet with no header. It's like beginning a conversation without a greeting.
I prefer to keep my own stylesheet headers short and simple—title, author, version—just enough to provide context.
The Luminous header:
/*
*/
Luminous master stylesheet
author: Michael Barrish
version: Sep 6 2006
Include a Table of Contents
Tables of Contents are rarely included in stylesheets, for reasons I've never understood. It is because most stylesheets are written haphazardly or follow a loose structure? Personally, I always include one, as it provides a simple overview of the stylesheet and makes it easier to find specific rules.
The Luminous table of contents:
CONTENTS:
- Grid
- Common Elements
- Header
- Main Column
- Side Column
- Footer
Use Sections and Order Them Logically
The section order of my stylesheets follows a consistent logic, one that enhances findability and helps prevent inheritance problems.
Sections require identifying headers, which must be contained within CSS comments to be excluded from processing by browsers. The styling of headers is a matter of aesthetic preference; however, I recommend making them prominent enough to be easily spotted on a quickly scrolling page.
A sample section header:
/
********************************************/
COMMON ELEMENTS
********************************************
For the Luminous stylesheet, the first two sections, Grid and Common Elements, contain site defaults. Styles that appear in subsequent sections often refer back to these rules, augmenting and in some cases overriding their declarations. Now, while CSS specificity gives greater weight to specific rules than general ones, regardless of their order in the stylesheet (e.g., the declarations of h2.highlight always override those of h2), this practice can cause problems and is best avoided. For example, when the same selector appears in two places in a stylesheet, the latter rule will override the former, often leading to unexpected results. (Moreover, use of the !important value, which should be kept to a minimum anyway, can further complicate matters.)
In short, it's best to follow the general-to-specific approach, not only to avoid inheritance problems but to maintain a clear and consistent stylesheet structure, one that makes it easy to find and edit existing rules, and to create new ones.
Again, consistency is the cornerstone. I always order my stylesheet sections to mirror a basic top-to-bottom HTML page structure. Thus, the Header section appears near the top of the stylesheet, after the site defaults, and the Footer section comes last.
Identify and Order Subsections
Always identify subsections. This is an extension of the practice, familiar to all skilled programmers, of including explanatory comments within programs and scripts. The idea, again, is to make the stylesheet as easy as possible to edit—by you and others, now and in the future.
In the Luminous stylesheet and elsewhere, I place simple CSS comments at the top of all subsections to serve as headers. For example:
/*
nav*/
As with stylesheet sections, I try to order subsections to mirror the basic top-to-bottom HTML page structure. This works best for those sections, like Header and Footer, which contain mostly global rules. However, for sections such as Main Column, which typically include an assortment of non-global rules that apply to specific sections or pages within the website, I usually divide the rules into subsections that correspond to website sections. Thus, all rules that apply to pages within, say, the About section of the Luminous website, are grouped together within the stylesheet, and this subsection is again identified with a simple header:
/* about */
When organizing subsections this way, I always place them in alphabetical order. Thus, the subsections within the Main Column section of the Luminous stylesheet begin with /* about */ (for the About section of the website) and end with /* weblog */ (for the Weblog section).
Finally, all Main Column rules that apply to multiple sections of the website are placed at the top of Main Column, before the various subsections, and are ordered alphabetically by element.
Alphabetize Properties
Speaking of the joys of alphabetization, I always alphabetize properties within individual rules. Always. Again, consistency has its rewards. Because I'm systematic in this practice, I never need think about property order. The order is always the same: alphabetical. This makes it easier to write rules, easier to read rules, and easier to share rules between stylesheets. Moreover, I never accidentally repeat a property within a single rule, possibly overriding a necessary declaration, because redundant properties are simply too easy to spot when ordered alphabetically.
Use CSS Shorthand
CSS offers several options for combining related properties and streamlining values. Together these shorthand practices help authors produce less bloated stylesheets.
To give a single example, the following two rules offer contrasting approaches to same end:
One rule, four properties:
#container {
background-color: #eee;
background-image: url(/media/bg.gif);
background-position: 10px 0;
background-repeat: no-repeat;
}
One rule, one property:
#container {
background: #eee url(/media/bg.gif) no-repeat 10px 0;
}
Like many expert authors, I prefer the shorthand version. Note, though, that for those new to CSS, shorthand rules can be more difficult to understand. In the end, one must balance this tradeoff. However, in my "perfect" stylesheet, shorthand is the rule.
Use Whitespace
A stylesheet with zero whitespace would work perfectly but be nearly impossible to read and edit. I strive for a judicious use of whitespace: just enough for good readability but no more. Once more, the key is—yes, you guessed it—consistency.
Here's a sample rule from Luminous:
a {
border-bottom: 1px solid #f4ead9;
color: #994303;
text-decoration: none;
}
As the example shows, I indent all properties one tab, insert a space after colons, and place the close brace on its own line, among other conventions. Some authors use less whitespace, some more. However, what really matters is consistency. Every rule I write looks exactly like this one. (One exception: I place single-declaration rules on a single line. However, this, too, I do consistently.)
I realize I'm repeating myself, but it bears repeating: consistency is king. Why? Because consistent authoring practices make stylesheets easier to write, easier to read, easier to understand, and easier to borrow from (which is something I do all the time: copying and pasting chunks of code from previous stylesheets).
Keep Hacks to a Minimum
While this has more to do with CSS authoring practices than stylesheet structure, hacks come at a price and are best avoided. This said, I use a sprinkling of hacks to address particularly nasty issues in IE6 and IE5x. What can I say, life is filled with disappointments and compromises, and for CSS authors, most of these begin at Microsoft.
My one recommendation about hacks, aside from learning all known workarounds, is to include comments about them in your stylesheets and provide links to documentation.
In Conclusion
Perfection is impossible. Sorry.
Be consistent. Use a logical, easy-to-understand structure.
Also: headers are nice. As is alphabetization.
Be consistent.
Published in CSS, Web Standards
What Is This?
This is a blog about better websites—how they're made and what makes them better. Think of it as Apocalypse Now but with the word Apocalypse changed to Quality and the theme shifted from madness to best practices in web development. It's written by me, Michael Barrish.
Song of My Professional Self
I celebrate myself, and sing myself. I build bulletproof websites using web standards and related best practices. I work with designers and companies needing expert style and markup. Clear and sweet is my soul→
Weblog Articles
Latest
- Vertically Center an Image with CSS - A New Method
- Today I came up with a different approach, one in which the image is loaded via inline CSS.
- Death of a Standardista
- I have no interest in building kick-ass containers for crappy content.
- Great Copywriting—Not for Robots
- Neither for the faint of heart nor the narrow of mind.
- The Death of TimesSelect and the Future of Web Advertising
- There's a lesson in this, and it's not that information wants to be free.
Popular
- Adblock Plus Must Die
- An anarchist superhero comes from the future to rid humans of ads forever.
- Clients and Copy
- When the copy sucks, the website sucks.
- Pipe Dream
- I just solved a longstanding CSS problem: pipe lists.
- Confessions of a Bad Designer
- I'm a one-trick pony, and my trick doesn't necessarily work.