CSS: Simple Rules for Better Organization and More Efficiency
Jens Meiert, May 15, 2008 / September 7, 2009.
This entry is filed under Web Development.
“Organization is not everything, but without organization, everything is nothing,” one of my teachers used to say, and right he is. Almost everything benefits from organization, and so does work with CSS – especially when working with many people. During the years I took special care of organizational standards mainly for HTML and CSS (German readers might know the coding guidelines I created for GMX and Aperto), and there should be enough “proof of concept”.
However, time brought additional refinement for my personal CSS coding guidelines, and I want to share the three basic rules I use for consistent organization and improved efficiency (by the way, this is what I referred to when announcing CS4 in January). I hope they mean some inspiration, please feel free to use, play with, and comment them.
Sort and Group by Selectors
Web developers taking the “module approach” tend to do this already, but it is quite worthwhile to standardize selector order, both for yourself and for the team involved. Currently, the order I defined for selectors in my projects is this (although it does not include all selector types):
*, html, body, h1, h2, h3, h4, h5, h6, p, address, blockquote, pre, ul, ol, li, dl, dt, dd, table, caption, tr, th, td, form, fieldset, legend, label, input, textarea, div, img, a, strong, em, abbr, q, cite, code, kbd, var, span, #id, .class
This sorting method works both “vertically” and “horizontally”:
ul, li, .note {}
ul {}
li {}
.note {}
The rule will get slightly more complex when talking about descendant selectors; I use to apply the same order (so e.g. p em, p abbr {}), but let simpler selectors go first (think p, p em, p abbr {}). Another “sub rule” worth mentioning is certainly the order applied to selectors like for example p and p.warning, where it would be p, p.warning (or p, .warning, fitting the above scheme again), both vertically and horizontally, too.
Admittedly, this gets kind of a rough description of what I use and with what I had good experience. Feel free to build on that; for instance, you might go for a “module-centric” way by only applying this order within CSS segments (like navigation styles and so on) – or to make it more specific.
Use Any Declaration Just Once
Exactly: Use any declaration just once. The reason for that is that on average, declarations are longer and thus add more weight to style sheets than selectors (and selector groups), and thus take more time to load. Another reason is that this is a nice argument to shake heads when CSS variables (not selector variables) come up – in many cases you probably don’t need them, at all.
Let’s see a realistic though shortened example (just imagine this style sheet contained, say, 50 rules):
h1, h2, h3 { font-weight: normal; }
a strong { font-weight: normal !important; } /* exemplary, take it as given */
strong { font-style: italic; font-weight: normal; }
#nav { font-style: italic; }
.note { font-style: italic; }
Applying the “any declaration just once” rule results in
h1, h2, h3, strong { font-weight: normal; }
a strong { font-weight: normal !important; }
strong, #nav, .note { font-style: italic; }
This saves a few characters (and load time) already, without necessarily getting into the way: After all, styling HTML documents is about presentation, so focusing on declarations first does work well.
There are, however, four important things to note:
- Overly long selectors can drive this method useless. Repeating selectors like
html body table tbody tr td p span.extraordinary-awesomish-class-namein order to have unique declarations doesn’t save much – but it might be a sign to use more compact selectors. - Be aware of CSS regulations: When a user agent can’t parse the selector, it must ignore the declaration block as well. If you run into trouble with this, just bend the rule accordingly (use the declaration in question twice).
- Keep the cascade in mind when using this rule in conjunction with the former.
- This organization and efficiency rule requires more attention when maintaining style sheets. Find a way to track changed and added declarations in order to get them in line again – this is not hard when using a more or less reasonable editor (showing line changes, for example), but needs to be incorporated into the workflow anyway.
Alphabetically Sort Declarations
There are I don’t know how many ideas how to sort declarations within declaration blocks, but the simplest and “cognitively least demanding” is alphabetical sorting. So instead of thinking measurements first, then colors, then sizes, and so on, just order alphabetically:
#content {
border: 1px dashed;
color: #000;
margin: auto;
padding: 1em 0;
width: 700px;
}
I know that other sorting methods (or none at all) have some friends, too, but it may be claimed that this is indeed simple and straightforward once you get used to it – which happens quickly.
Example
In order to show all these tips in action together (as well as inconsistencies on my behalf
), here’s a part of WHWS’s 2006 standard style sheet:
@media screen, projection {
* { margin: 0; padding: 0; }
html { background: #000; color: #ccc; font: 87.5%/1.5 optima, arial, sans-serif; text-align: center; }
body { margin: 1em 0; }
h1, h2 { font-size: 1em; font-weight: normal; }
h1 { background: url(/media/logo.jpg) no-repeat; height: 366px; text-indent: -999em; width: 620px; }
h2, p { margin: 0 .5em; }
p + p { text-indent: 1em; }
p#ref { background: url(/media/end.jpg) no-repeat bottom center; margin: 1.5em 0 0; padding-bottom: 179px; }
ul { margin: .5em 0 .5em 1.5em; }
ul#lang { list-style: none; margin: .5em 0 1em 1.5em; }
ul#lang li { display: inline; }
div#show { margin: auto; text-align: left; width: 619px; }
div#whws { background: url(/media/tape.gif) repeat-y top center; margin: 42px 0; }
div#whws + div { position: relative; }
a, strong { color: #fff; }
strong { font-size: 1.3em; line-height: 1.0; }
kbd { font-family: optima, arial, sans-serif; }
}
At the end of the day, just use what’s best for you, and be it that you feel inspired by these rules to try them in some pet projects or in the aforementioned module-specific way. Which is, actually, a good approach in quite complex projects.
Final tip: CS4 is best served with TWBHT.
Read More
Enjoy the most popular posts, probably including:
Comments
-
On May 16, 2008, 0:42 CEST, Duluoz said:
Great article as always Jens.
Choosing a great mono-spaced typeface also helps you be more efficient in working with any code. There are many typefaces created specifically for making code easier to read and comprehend quickly. Just like serifs help us read a newspaper or a book comfortably, so will a mono-spaced typeface help us see code more comfortably.
-
On May 16, 2008, 9:45 CEST, Jens Meiert said:
David, thank you. Concerning fonts for code, however, I intentionally take this way in order to avoid the problem that the alternative font does not typographically fit the usual type. But this is, of course, subject to change once I find a working and actually better alternative

(By the way, this post is also available in German.)
-
On May 16, 2008, 11:19 CEST, Alan Gresley said:
I do believe the best way to learn organization in one’s CSS is to have dis-order first and while you fixing this dis-order, you’ll remember not to make the same mistakes again.
You can apply that to many things in life, even the development of the web.
-
On May 16, 2008, 16:00 CEST, Trevor Davis said:
I agree 100% about alphabetizing CSS properties. I started doing it about a year ago, and now I cannot imagine doing anything else.
It also helps a lot for consistency when you are working with a team of people.
-
On May 17, 2008, 3:36 CEST, Jens Nedal said:
I like the alphabetical order approach for declarations.
In our team we use a background ro foreground and outside to inside approach, looking at the box model.like
… {
background: …
margin: …
padding: …
border: …
…
} …This suited us well since the boxmodel is something that is always in your head. Its more along the lines of your selector sorting and grouping. Not totally adhereing to the boxmodel order.
-
On May 19, 2008, 11:10 CEST, Jens Meiert said:
Alan, interesting point … chaos’s not necessarily bad

Trevor, glad to hear that …!
Jens, I’d suspect there to be inconsistencies, or did you really have good experience with that approach, has there been enough “discipline”?
-
On May 19, 2008, 15:33 CEST, Alan Gresley said:
Jens, I’d suspect there to be inconsistencies, or did you really have good experience with that approach, has there been enough “discipline”?
I would go along with Jens Nedal’s approach but in a different order (seen in my CSS), like:
font-size: ..
width: ..
height: ..
padding: ..
margin: ..
border: ..
background: ..Then repeated rulesets later in the cascade for progressive enhancement and hackery.
I almost always have background last since mine usually take up a whole line.
-
On May 20, 2008, 18:40 CEST, Duluoz said:
To be honest - I never gave a rats behind about the order of the selectors. I work with several other developers right now and we just throw any old selector anywhere (outside of how we want things to inherit obviously). I can’t say that I’ve ever been “confused” or misunderstood something because of the order.
You know the scene in the movie “The Matrix” where the guy is looking at all the code flying down the screen and he says he just learns to “see the matrix, not the code”? Thats kind of how myself and anyone I know that deals with CSS everyday sees things. We see it all as a whole.
I think its a nice habit to have, don’t get me wrong, I just never put much value in it.
-
On May 25, 2008, 1:53 CEST, Jordan Clark said:
I’m another fan of alphabetizing CSS properties. It just makes sense, and helps to ensure that you never redeclare a property by accident.
However, that’s not to say that I don’t make the odd exception to this rule. For instance, with the
positionproperty, I like to keep the directional values (top/right/bottom/left) directly below it so that I can quickly work out what’s happening, e.g.:
.example {
border: 1px solid;
font-weight: bold;
position: relative;
top: 10px;
left: 10px;
width: 100px;
}
(It makes sense to me, anyway!)
-
On May 25, 2008, 15:29 CEST, Jens Meiert said:
David, nice one. It’s of course great, yet the goal to see the entire picture, no matter what (and I can’t really say that I’ve got specific problems with unorganized CSS code either). It’s just that some simple order does especially help when eager to structure and to simplify teamwork.
Jordan, I know what you mean, sorting position related declarations this way is a little bit “counter-intuitive”
I can relate to the way you solve this but go for alphabetical sorting nonetheless since I find that exceptions are always one thing more to remember, to explain, and to reason, thus suspecting “strictness” to be simpler
-
On July 2, 2008, 0:20 CEST, Tedel said:
I liked your article. My congratulations.
-
On October 10, 2008, 22:02 CEST, Joel said:
I just wrote a tool that converts single-line and multi-line css:
-
On October 11, 2008, 13:29 CEST, Jens Meiert said:
Tedel, thanks!
Joel, neat, I even consider adding this to UITest.com.
-
On July 9, 2009, 21:32 CEST, Jonny Axelsson said:
I follow a “Most important first” organisation of properties, starting with layout properties like ‘display’ and ‘float’, generated content, box model, colour, typography, and aural properties.
The rationale is simple, it makes debugging easier, you can quickly scan to likely point of error. However it probably would fail with a large organisation and it depends on everyone having a good command of the entire CSS 2.1 vocabulary. With the much larger CSS3 vocabulary it would be considerably harder to maintain.
-
On December 25, 2009, 18:40 CET, Steffen said:
As far as I understand the grammar from the css specification
'{' S* declaration [ ';' S* declaration ]* '}' S*
or the verbal explanation (”semicolon (;) separated groups”) the trailing semicolon in the declaration block is not only unnecessary but also invalid.
I have to admit that I couldn’t find the reason why the validator doesn’t list it as an error though.
Come on Jens, save some more bytes and remove the semicolons for the sake of your never ending quest for speed