Writing Lean CSS
The goal of using CSS in our web pages is to more cleanly separate presentation from structure. But if our CSS files are too large and/or messy, it would seem that all we’re doing is taking the presentation out of the XHTML and dumping in on the floor. No real rhyme or reason, just a bunch of presentation information to wade through. While I am no expert on the full and complete use of CSS, I thought I’d share a few tips on how I learned to keep my CSS a little more organized and easily editable.
Shorthand
Using CSS shorthand is probably the quickest and easiest way to cut down on your overall file size while making your files easier to update at the same time. There are already very detailed articles on CSS shorthand, but let me give a brief overview of the techniques I use most often.
Margin and Padding
As you probably know, margins and padding can be declared using margin-top, margin-left, padding-right, padding-bottom, etc. But all ‘sides’ of the box can be described at once using shorthand. The model goes like this:
/* Usage - margin: top right bottom left; */<br />
margin: 10px 2px 5px 8px;
This would define the margin-top to be 10px, margin-right to be 2px, margin-bottom to be 5px, and margin-left to be 8px. Now we don’t have to declare every one of these values. If all 4 sides are to be the same 10px, we can simply declare margin: 10px; and the 10px margin will be applied to all 4 sides. If we declare the first two values, such as margin: 10px 5px;, a margin of 10px will be applied to the top and bottom, and 5px to the left and right sides. If we declare 3 values, margin:0 5px 10px; a margin of 0 will be applied to the top, 5px to the left and right sides, and 10px to the bottom. All this works the same for padding, but be sure to take the box-model differences into account when using padding. And remember, when declaring a value of 0 to any of these positions, no units are necessary. 0em is the same as 0 px is the same as just 0. No need to include the units.
Backgrounds
When applying background colors and images together, there are a few properties that you will most likely use: background-color, background-image, background-repeat, and background-position. When using these in combination, they can be applied as follows:
/* When you want to apply the following styles */<br />
background-color: #CCC;<br />
background-image: url(bg_image.gif);<br />
background-repeat: repeat-y;<br />
background-position: top right;<br />
<br />/* All of these can be combined into */<br />
background: #CCC url(bg_image.gif) repeat-y top right;
Any of these declarations can be left out, but when undeclared, the browser defaults will be used, typically transparent background, no background image, full repeating, and top left positioning.
Fonts
As it is with backgrounds, font declarations can be combined into one concise line.
/* When you want to apply the following styles */<br />
font-style: italic;<br />
font-weight: normal;<br />
font-size: small;<br />
line-height: 1.4em;<br />
font-family: Verdana, Helvetica, sans-serif;<br />
<br />/* All of these can be combined into */<br />
font: italic normal small/1.4em Verdana, Helvetica, sans-serif;
Again, any of these declarations can be left out, but the browser defaults will be used. It is also good to note that browser defaults vary much more with fonts than they do with backgrounds.
Use the Cascade
There’s a reason they’re called ‘Cascading Style Sheets.’ The document cascade is a relatively in-depth process, but when using a single linked style sheet, the document cascade can be simplified. Many style definistions will be inherited by elements from their parent element. Browser defaults often interrupt this cascade, but rules like font and text-align will mostly be inherited throughout your document. I say mostly because there are a few browser bugs, mainly IE, that you have to deal with on this issue.
To more fully utilize this cascade we can take advantage of this inheritance and not have to repeat these definitions. For example, say we want most of our document text to be the same. We place that definition in the body selector, and that font will (or in the case of IE, should) be inherited throughout the entire style sheet. IE has a little problem with tr and td elements not inheriting fonts, so to apply a font to an entire document we do the following:
body, tr, td {<br />
font: normal small/1.4em Verdana, Helvetica, sans-serif;<br />
}
Similarly, if any of your headlines and paragraphs will have the same margins, those can be grouped together as well.
h1, h2, h3, p {<br />
margin:0 0 15px;<br />
}
We can also use this cascade in our selectors. Say, for example, I have a div tag with an id of “article.” Inside this article div I want the paragraphs to have a specific margin. Instead of having to put a class of ‘article-paragraph’ on each p in the article div, I can use the following selector:
/* This will select any p inside <div id="article"> */<br />
#article p {<br />
margin:0 0 15px;<br />
}
Also, the cascade runs in the direction of specificity. Yeah, that sounds really complex, but all it means is that if you specify, say, a font in the body selector, you can overwrite that font definition by using a more specific selector. For example:
body, tr, td {<br />
font: normal small/1.4em Verdana, Helvetica, sans-serif;<br />
}<br />
<br />
h1, h2, h3 {<br />
font: medium Georgia, Times New Roman, Times, serif;<br />
}
We have declared that everything inside the body should have a specific font style, but because the h1, h2, and h3 selectors are more specific than the body selector, the font definitions in that selector take precedence over the ones in the body.
A Few Good Tips
Jacob Rask suggested that you could eliminate all default padding, margins, and borders by using the following CSS:
* {<br />
padding: 0;<br />
margin: 0;<br />
border: 0;<br />
}
This works very well, but the only thing I’ve found is that you will have to declare some margin/padding for any ul or ol elements in order for them to display correctly.
John Nunemaker suggested that you keep all your CSS declarations on one line. It does keep things a little neater, as long as you’re comfortable reading and editing the file like that.
Conclusion
This is in no way a comprehensive list of ways to keep your CSS files more organized. It’s just a few tips I’ve picked up along the way, from my own work and from others. If you have others that save you time, let me know about them. I’ll welcome any way to save myself a few seconds or a few bytes.
Post and Author Info.
Published September 28, 2004 by:
Commenting is currently off for this post.
So far there are 16 comments.
I’ve seen it recomended that you flag your body elements with a class that is specific to that page, even if you aren’t immediately using that class when you write the page. Example: Take a page called titled “contact.html” and put a class of “contact” on the body tag.
This only adds 15 characters to the file, but can save you lots of space in your CSS. When you want to apply a specific styling to an element on this page which already has a class, id, or both, then instead of wrapping it in another span or div, you can just add body.contact ul.nav { styles: blah } to your stylesheet. This can also help you avoid editing your html docs to add styles to elements.
September 28th, 2004
One option would be, once you’re ready to publish your site, save a copy of the style sheet with all of the line returns and tabs stripped out. Then if you need to edit, use the ‘readable’ copy and then strip it again before publishing.
(not a personal practice)
September 29th, 2004
flumpCakes has a handy CSS Optimiser, which works better and better by the day. It’ll prove easier than stripping it manually.
October 3rd, 2004
Great site and great article.
Just clarifying something you wrote about fonts (Again, any of these declarations can be left out, but the browser defaults will be used.). Actually, in order for the font shorthand to work, you must specify the size and font family, in that order, e.g.,
example {font: 100% arial;}. Don’t know why, but that’s what you need to do.Thought you might be interested in something I created for my company. It’s a CSS Style Guide. I recently put this together after I hired another developer and saw the need to have our CSS files click. Check it out: www.jjpg.com/Internal_docs/css_guide.php.
J.
October 8th, 2004
Hi,
nice article! Just wanted to mention, as allready done in the article you mentioned (http://home.no.net/junjun/html/shorthand.html)
that sometimes shorthands can give buggy results in some browsers! Took me some frustrating hours to find out! You know, hours of stripping and isolating code to find out were the margins or borders have gone in IEwhatever, untill finally in a desperate attempt changing a shorthand to a full property, and Who! proplem solved… I was using shorthand from the start, but now I try to watch out a bit.
greetings, Matthijs
October 8th, 2004
Shorthand only tends to get buggy if you don’t do it in the correct order, some browsers are pickier than others. In fact, in the case of the shorthand for font, putting certain things in the wrong order actually gives validation errors.
October 20th, 2004
I don’t know how many times the global rule (setting margins, paddings, and borders to zero) has saved me many a headaches. It really cuts down the time of trying to implement a correct box model website.
December 4th, 2004
Thanks for a great article, Steve. What could I say?
Read, print, hang on the wall, stick to it.
Thanks!
With warm greetings from Germany, Vitaly Friedman, http://www.alvit.de/vf/
April 14th, 2005
I agree with #6/chris, one has to be careful about the order in some cases.
I’ve also found that it’s not only IE which has trouble with table/tr/td inheriting font details, but pretty much everything — so you always have to declare your font properly for tables.
As for organising the CSS, I found that indenting the CSS declarations as appropriate — if something will surely be a child and be affected by the parent’s
position: relativefor example — can help a lot (example in http://ralesk.technoweyr.co.uk/’s source due to IE not liking if I@importor<link>it).June 19th, 2005
Testing
December 14th, 2005