Post Archive
› September 26, 2005
Maintainable CSS
Simon Willison put a call out for advice on creating maintainable CSS. Here are some collected thoughts on the matter, please keep in mind that quite a bit of this is just personal preference.
- Use as little CSS as possible, remove styles and parts of styles not being used or that were experimented with in the design process.
- Use unique IDs as much as possible, these of course should only be used once per page.
- Only use classes on elements that have any chance of being repeated on a page and in different locations, if the element is going to exist in a predictable location, target a sibling element of an ID'ed container instead - at least whenever possible.
- Use as few browser hacks as possible, and document them with comments
- Introduce your stylesheets with comments and explanation of how the particular sheet fits in with other sheets and with the site.
- I am a proponent of multiple stylesheets for large and complexly styled sites, however keep in mind that in some environments the extra http calls will not be appreciated.
- When considering multiple stylesheets, first make sure its really worth while - a single long CSS file can at least be searched easily ("find all instances of h2")
- When using multiple stylesheets, I like to think of them as an extension of the cascade. A base styles file contains CSS rules that can be applied on every page, then create more specific sheets perhaps based on section.
- Use a predictable format, some like grouped attributes, or specific orders. Personally, I like each attribute on it's own line, but as long as the format is consistent.
- Group your styles with short and precise labels via comments
- If you choose to wipe out default browser styles and start with a clean slate (see Eric and Tantek), document this somehow. I've found this to be very powerful in many ways (cross browser consistency for example), but it can be disorienting if you're adding to a style sheet setup this way
I'm going to consider this post open, and will add more to the list above if I think of other tips. Since this list is riddled with personal preferences, I won't be adding suggestions to it, but please feel free to add comments to the post, or maybe better at Simon's post or at the wiki page.
Comments
1. September 27, 2005 01:46 AM
2. September 27, 2005 08:34 AM
Chris K Posted…
More of a personal preference than a rule, but I try to order my CSS the way the page reads on the browser (ex. header information first, etc.). Nice post and great points. I'm in the process of redesigning an incredibly large site using CSS with multiple styles. This helps me keep my focus clear as I put it together.
3. September 27, 2005 10:01 AM
Nate Posted…
That's interesting Chris. In the past I've thought of my style rule ordering to be "outer to inner", for example when thinking of HTML like an onion, but really that almost always means doing what you suggest.
David - that sounds like good a very good practice to pick-up, I'm not sure I have the discipline for it, but it sounds worth a shot.
4. September 27, 2005 02:18 PM
Kevin McDonagh Posted…
When you can define #IDs and .classes try to make your names related to how the object relates to the design rather than the content it holds. This makes your style sheets reusable. For example, if you have a class for images at the top of your page and another for a list of adverts in the side bar.
Instead of using:
class="mainImage" & class="advertList"
You could use:
class="topImage" & class="sideList"
At first you'll be tempted to rename your #IDs and .classes to names that will make more sense while you’re originally making the design but I can guarantee that on return to the same design you'll find it much easier to navigate and comprehend.
5. September 27, 2005 02:24 PM
Nate Posted…
Kevin, that's interesting, I'd assume you'd want to go the other way. I thought you'd want to tie your classes to the content rather than the context, what if someone later wants to move the "mainImage" from the top area? Although I'm not sure I'm right about this.
6. September 27, 2005 02:44 PM
Kevin McDonagh Posted…
Using your example; if someone were to move the main image from the top area it would no longer warrant being called "topImage" and you would require a new class. You could then remove the redundant "topImage" and replace it with "1stContentImg" (for instance). I'll admit this style of classes is very prone to misinterpretation but this is only due to a lack knowledge on my part of standard terms for specific graphical elements of a page design.
I found after transferring large style sheets to a new site, the content that once lent itself to the side bar now is more fitting for the top of the page. If this happens then I'd have to go through each instance of "sideAds" being inherited and rename it to "topAds". The naming is hard to keep organised but I try to use popular web design concepts such as:
For a 3 column design the divs would be:
#leftCol / #middleCol / #rightCol
7. September 27, 2005 03:25 PM
Nate Posted…
Well my thinking is that ideally you'd label your groupings to be layout-agnostic. For instance if you had a handheld specific CSS, the three columns might not have any relevancy in that format. Instead if you had "#primary", "#secondary", and "#minor" or some such, then the grouping can be reused and modified without changing the HTML. But I agree, if you change the HTML, might as well update the styles.
Having said all this, I looked back at a site I worked on recently, and indeed I mix and match. I use "#topbar" because I imagine that content will always be at the top, regardless of format. And for better or worse I use "#footer". The rest though is design agnostic, which I'm still thinking is better.. but of course it's a matter of preference.
8. September 27, 2005 03:42 PM
Kevin McDonagh Posted…
That is indeed a better naming scheme. It might be a good idea for people to start publishing their naming schemes for CSS elements or just thorwing some ideas around for a standard. I'm sure a lot of web design agencies probably do have a common naming standard. As schemes get very intricate though it’s hard to see how one would name the third child of the second list embedded in the second column.
9. September 27, 2005 04:37 PM
Nate Posted…
Well that's just it.. "third child of the second list embedded in the second column" refers to the layout, where if we use #primary, #secondary for the outer structure, and content-specific for the inner workings, it's a bit easier (I think).
So the suggestion based on your example could turn into:
#secondary li#fav_song_three { color:red; }
Of course this is just my take on it, I agree that some sort of informal standard could be a great idea.
10. September 27, 2005 06:46 PM
Sid Posted…
I tend to use #primary, #secondary, and #peripheral. Primary holds the real guts of the page, secondary holds its supporting data (e.g. local section menus, associated links, and so on), and peripheral holds everything else (e.g. adverts, login box).
I tend to wrap primary and secondary in a parent div as they are closely related (called content or main depending on my mood). This then enables me to re-order the columns using simple use of floats. All source ordered so that the primary stuff comes first, then secondary, then peripheral. Switch the floats and you can move the secondary column from right to left of the page just by editing CSS - no HTML edits at all.
I often class the first and last items in lists up (literally 'first' and 'last') as they often require special attention. I sometimes stick in odd/even classes too.
Works for me
11. September 27, 2005 06:49 PM
Sid Posted…
Oh, and don't name your classes and IDs with actual details about how they are presented (e.g. LeftCol). You shouldn't need to rename you classes and IDs when you redesign. Name things what they are, not what they look like. Just ask Zeldman.
12. September 27, 2005 11:10 PM
Ethan Posted…
David Lindquist said:
One (admittedly anal-retentive) habit I have is to alphabetize all of my declarations. It helps me when I am quickly scanning through the file. I always know that backgrounds and borders are near the top, positions and z-indexs are near the bottom. I don't worry about putting them in the proper order while quickly developing the stylesheet though. I use my text editor's sort-lines feature when I do clean-up.
My prefered method is to introduce my declarations in the order that they appear on the page. This helps me more than alpabetizing, because I can often look up and figure out where a declaration for a certain object is without looking at the page's source.
13. September 27, 2005 11:56 PM
Nate Posted…
Ethan I think when David says "declarations" he's speaking of the meat and cheese of each rule set.
So I believe he means:
#primary h1 {
background-color:#000;
border:1px solid #fff;
font-family:verdana, sans-serif;
text-align:center;
}
See how background is followed by border, then font-family... I think those are the bits David is ordering alphabetically.
14. September 28, 2005 03:38 AM
Vasilis Posted…
I start my styles with the name of the tag. For example #divContent, #ulNav or .pComment. It makes it easier to see which element I'm working on.
15. September 28, 2005 06:00 AM
Kevin McDonagh Posted…
"I tend to use #primary, #secondary, and #peripheral. Primary holds the real guts of the page, secondary holds its supporting data (e.g. local section menus, associated links, and so on), and peripheral holds everything else (e.g. adverts, login box)."
Thats a great idea essentially but what happens when your style sheet spans across the organisation of maybe 20 pages. You may have sections that differ dramatically from the 1st page. In which case actually it may be a good idea to use " body.page1 #primary". Just answered my own question :/ .
s for starting tags with the name of the element that holds them, I believe that is a redundant, code bloating practice. Sufficient comments should be able to document your tags satisfactory.
16. September 28, 2005 02:10 PM
Sid Posted…
Yes, I often class the body with with the name of the section - so stuff like body.news and body.events. This means you have sufficient hooks to alter the layout to a fair degree. Although to be honest there's not normally much need to do too much as most pages follow the same format. The real change and variety is within the #primary area - but then that is custom code per page and so no problem.
I also tend to include the 'template' name in the class on the body tag - so I can make the necessary adjustments for two or three columns (or whatever) using just one style sheet.
I agree with Kevin - naming classes with the elements they effect is a bad idea.
17. September 29, 2005 12:01 PM
Ciaran Posted…
Vasilis, surely if you want to include the element name in your style definition you'd be better off using DIV#Content, UL#Nav or P.Comment rather than #divContent, #ulNav or .pComment ?
18. September 30, 2005 02:14 AM
Vasilis Posted…
From the reactions I see that many people don't think it's a good idea to use the element name in the style definition. I still don't see a clear reason why. I'm starting a new big project today. I'll try and do it your way and see if I can find a good reason why it's better.
19. September 30, 2005 07:51 AM
Larry Israel Posted…
I like to use only a single global style sheet. I tend to end up with a dozen or more sections (at least on sites with at least a few dozen pages), each clearly labeled with a commented heading.
I start by zeroing and setting just a few standard defaults and boilerplate. The next section is usually where I define fonts and colors. Then page layout in its own section.
Then I start down the page with a section in the style sheet for each area of the web pages: header, top navigation, content, etc. These style rules exclude page layout and other more-global styles that were defined at the top. Some of these are divided into several subsections, especially in the content section with headings, lists, tables, forms, images, and miscellaneous (etc.).
Below all that (below the footer section), I have one or more sections with site-sectional and single-page only style changes. One of these is always a home page-only section. Many of these rules are overrides of previously-defined styles. (I apply them via classes or IDs in each body tag.)
20. September 30, 2005 10:35 AM
Nate Posted…
Vasilis: There's nothing inherently wrong with having the element in your class and ID name, it's just a name after all. I think the negative reaction is because it implies a tight correlation with the element without really enforcing it. So one could attach #divMyBox to an unordered list and really make things confusing, whereas div#MyBox will only apply if #MyBox is attached to a div.
21. September 30, 2005 07:44 PM
iEdML Posted…
Aside from it being unnecessary (p.comment vs .pComment), the confusing aspect is if you or somebody else then goes on to use li.pComment.
22. October 3, 2005 09:40 PM
J. J. Posted…
I found Starting with CSS: Revisited by Faruk Ateş to be helpful, too. He happens to reference Bowman's CSS Organization Tip 1: Flags (I don't think he has posted a Tip 2 yet!). Molly's Integrated Web Design: Strategies for Long-Term CSS Hack Management from a year ago still has important principles.
23. October 8, 2005 05:08 AM
Mike Posted…
Concerning properties order, i find quite convenient to define things like this :
#MyId {
Position
display ==> Overhaul aspect of the object, its position in the page
float
clear
left, right
top, bottom
width ==> dimension, etc.
padding
margin
background ==> start visual changes
border
font
list-style ==> text styling
color
etc.
}
In fact, i put the properties that have the more impact on the displaying of the page on the top. Well, it's just a matter of convention and keeping it i think...
24. October 9, 2005 03:20 AM
25. October 10, 2005 12:41 AM
Stoyan Posted…
http://www.phpied.com/css-coding-conventions/ - Some ideas on using coding style and conventions to improve maintainability. Java and PHP (through PEAR) have "official" coding conventions, why not CSS?
26. October 10, 2005 05:11 AM
trovster Posted…
I have a TOC at the top, then I separate in to *General*, *Headers* then containers, working from the top down, so *container*, *content*, *sidebar*, *footer*, *navigation*. Then if it's a smal site, and I only have one stylesheet, it's followed by each page specific styles. If it's a large site, then I include these with @import.
I'm now thinking that, instead of using @import within the stylesheet itself, to include the general.css, I should use the HTML link. This way the general.css is cache, and the cascade is more obvious. @import must be at the top of the CSS, which begs the question, are the rules below overwriting the imported ones?
Mike: That's how I'm trying to organise mine now. With position/float, top/left, then width/height/margin/padding, then "pretties" such as font and I usually put background last.
class="topImage" & class="sideList" and #leftCol / #middleCol / #rightCol - this means you're mixing STYLE and MARKUP, which best practices in web standards is trying to avoid. When you change the style, you shouldn't have to change the markup & CSS.
27. October 10, 2005 03:35 PM
Terrence Wood Posted…
Nice Article.
I generally follow the cascade and html source order working from block levels down to specific classes, and split out styles by specific use (e.g. complex forms or tables, carts etc) so they are only loaded when required. Specificity of the selector usually indicate which part of the document the rule applies to.
I develop for CSS2.1 capable browsers first, and group and work arounds (I'm looking at you IE) together at the end of the file.
I'm always mindful of download time and server calls, and I often repeat selectors and combine rules, rather than slavishly imposing a top down structure (e.g. Header, Content, Nav) if I can save on page weight.
I use 2-3 letter id and class names instead of long descriptive names, and depending on the complexity of the document, I may need to make a glossary in a comment block.
I encourage people to keep development and production copies of external files and not send fully commented files to browsers.
David Lindquist Posted…
One (admittedly anal-retentive) habit I have is to alphabetize all of my declarations. It helps me when I am quickly scanning through the file. I always know that
backgrounds andborders are near the top,positions andz-indexs are near the bottom. I don't worry about putting them in the proper order while quickly developing the stylesheet though. I use my text editor's sort-lines feature when I do clean-up.