Please note that you may have been redirected (you might like to make a note of the URL in the address bar of your browser and update accordingly) This is a permanent archvie but is no longer actively maintained. Please visit http://joshuaink.com for the latest updates.

Avoiding classitis

Thursday June 9, 2005

With a few of my compadres taking a more active interest in web standards, I find myself in the position of tea swilling consultant in chief. Which all boils down to more writing preaching. So, continuing along the theme of "simple introductions", here is a look at two methods I employ to avoid the overuse of classes.

Note: Those of you a bit further down the line may have something to say about the choice of an ID on the body tag due to CSS signatures and the likes, but this is way ahead of our particular game and so I have chosen an ID simply to save confusion. It is also a perfectly valid way of doing things.

Sometimes it's unavoidable

Perhaps the one "missing feature" of Internet Explorer that frustrates me most is adjacent sibling selectors. As an example, here is a list of links styled as a navigation bar using only adjacent sibling selectors, not a class in sight. But it does not work quite as expected in Internet Explorer, oh no siree. It does degrade quite gracefully in IE but out there in the real world, where IE is king, it's probably not going to be what we want. In this situation there would be little choice but to give each list item a class.

The point I am trying to make here is that, because of lousy browser support for nice CSS features such as adjacent sibling selectors, extra classes are sometimes inevitable. This aside, we can still take some steps to reduce them.

ID on the body tag

I came to this later than most but it is one of things I wish I'd know about when I was first starting. I really could spend all day going through examples of just how powerful an idea this is but let's just do something simple to whet your appetite.

Let's say you want a coloured box on your pages, you want it red on the Home page but green on the About page. You might, as this example shows, apply a class to the div and call it something like class="red-box" for the Home page. You might then put another div in place for the About page and give it class="green-box", as shown in this example. The HTML for these two boxes might look something like this:

  1. <div class="red-box">
  2. <p>Contents</p>
  3. </div>
  4. <div class="green-box">
  5. <p>Contents</p>
  6. </div>

And the CSS a little like this:

  1. .red-box {
  2. background:#900;
  3. padding:1em;
  4. width:40%;
  5. margin:0 auto;
  6. border:3px dotted #000;
  7. font:77%/160% Arial, Helvetica, sans-serif;
  8. color:#FFF;
  9. }
  10. .green-box {
  11. background:#9C0;
  12. padding:1em;
  13. width:40%;
  14. margin:0 auto;
  15. border:3px dotted #000;
  16. font:77%/160% Arial, Helvetica, sans-serif;
  17. color:#FFF;
  18. }

Three days later you decide that the Home page should have the green box and the About page the red, doh! Time to move around that HTML.

If we had, instead, given the div a more meaningful class name, let's say for example class="alert-box" and applied an ID to the body tag (<body id="home"> and <body id="about">) it would have been a lot quicker for us to swap around those colours. The HTML for both of those different coloured boxes might then look something like this:

  1. <div class="alert-box">
  2. <p>Content</p>
  3. </div>

The CSS could then be altered to work with the body ID, thus:

  1. #home .alert-box {
  2. background:#9C0;
  3. padding:1em;
  4. width:40%;
  5. margin:0 auto;
  6. border:3px dotted #000;
  7. font:77%/160% Arial, Helvetica, sans-serif;
  8. color:#FFF;
  9. }
  10. #about .alert-box {
  11. background:#900;
  12. padding:1em;
  13. width:40%;
  14. margin:0 auto;
  15. border:3px dotted #000;
  16. font:77%/160% Arial, Helvetica, sans-serif;
  17. color:#FFF;
  18. }

We can also take this a step further and optimise the CSS a little. As long as we know that every instance of .alert-box shares some common styling, and provided we are using an external style sheet, we could change the CSS to this:

  1. .alert-box {
  2. padding:1em;
  3. width:40%;
  4. margin:0 auto;
  5. border:3px dotted #000;
  6. font:77%/160% Arial, Helvetica, sans-serif;
  7. color:#FFF;
  8. }
  9. #home .alert-box {
  10. background:#9C0;
  11. }
  12. #about .alert-box {
  13. background:#900;
  14. }

Every instance of the .alert-box div now shares a common set of styling rules and we adjust each as we like depending on the part (e.g. Home or About) of the site we are in. So now our Home page example is green and our About page example is red and changing them back would take a few moments in the CSS file, whilst the HTML remains untouched.

Making IDs work harder

A good example of classitis, and something I see quite frequently, is a div used for the page head with a H1 inside. The HTML often looks like this:

  1. <div id="header">
  2. <h1 class="header-heading">The page heading</h1>
  3. </div>

The CSS that follows may end up looking like this:

  1. #header{
  2. width:80%;
  3. padding:1em;
  4. height:150px;
  5. background:#FF0;
  6. border:1px dotted #000;
  7. }
  8. .header-heading{
  9. font-size:90%;
  10. color:#000;
  11. text-transform:lowercase;
  12. }

Unless, for some reason, there are going to be multiple H1s -- all in need of their own style -- within the header div, we have no need of the class and can do this instead:

  1. <div id="header">
  2. <h1>The page heading</h1>
  3. </div>

The CSS that follows may then end up looking like this:

  1. #header{
  2. width:80%
  3. padding:1em;
  4. height:150px;
  5. background:#FF0;
  6. border:1px dotted #000;
  7. }
  8. #header h1{
  9. font-size:90%;
  10. color:#000;
  11. text-transform:lowercase;
  12. }

If we take a look at the example with the class and compare it to the example without, there is no difference in how it looks.

Conclusion

The benefits of reducing the amount of classes in your code may not be immediately apparent from looking at the simple examples given above. When applied to a complete site build, however, it can mean a significant reduction in the "weight" of the site; less CSS, less HTML, less time taken and a site that is easier to re-style on a whim.

Avoiding classitis does take practice but the key is planning. Sit with your design comps for a while, and start to plan how the HTML will be marked up, what can be shared? How can I/is it possible to target specific elements without using a class? As said, a few extra classes may be unavoidable due to crappy browsers but that's no excuse for not at least trying to avoid the dreaded classitis.

Further reading

  1. AkaXakA

    1706 days ago

    Good guidelines :)
  2. Joshua Brewer

    1706 days ago

    Nice one John. It’s these little things that really highlight the power of CSS. Oh, and I really agree on the disappointment of IE not supporting adjacent sibling selectors – sure would make some development processes alot quicker!

    Some day…
  3. Alex Giron

    1706 days ago

    Great tutorial…. Cheers!
  4. Martin W

    1706 days ago

    That Professor monicker is going to start to stick you know Prof!

    Good work as always fella – can’t believe you found the time! ;O)
  5. Thomas B. Aschim

    1706 days ago

    Just what I’m saying! Except, I don’t – but you do… Way to go!
  6. kartooner

    1706 days ago

    Well written John! Thanks for the tip.

    I never really understood how to use body id’s effectively, but now I do! Thanks chap!
  7. anonymous

    1706 days ago

    I fink your site sucks, delete it now!
  8. Joshua Kendall

    1706 days ago

    Interesting tutorial…to say the least, but I am a little disappointed that you didn’t make “adjacent sibling selectors” an acronym :)
  9. Justin Reid

    1706 days ago

    Good article. Short, to the point with easy to understand examples. You mentioned in the intro the body tag id signature. These obviously can’t work together as is, but there is a simple solution (one that I’m sure your aware of but didn’t address here because it’s a little off topic). It’s good practice to put a div just inside the body tag and give it an id=”wrapper”. Not only does this make sure that only block level elements appear immediately inside the body tag but it can also be a good tag to add a page specifc class to.

    >body<
    >div id=”wrapper” class=”homepage”<

    That way you can accomplition the same type of speciation through contextualization that you wrote about in the article, but it leaves your body tag open for it’s on signature

    >body id=”mysite”<
    >div id=”wrapper” class=”homepage”<

    Giving users another hook into your page so that they can customize it to their needs.

    Thoughts?
    -Justin
  10. Chris

    1706 days ago

    Thanks John. Could have used this two months ago. I certainly had no idea about the body id technique. That just changed a whole lot of things for me.

    Much appreciated.
  11. Matt Wilcox

    1706 days ago

    Good post John – though I’m still not understanding the point of an ID on the body element. Unless this a method for styling different pages from a single CSS file? Which would seem messy if that is the case, surely it’s not a good idea to style a website with a single css file?

    I tend to write a master.css which contains site-wide styling rules and then, for example, an about.css for styling specific to the about page. The about.css then includes the master.css, and if it needs to overide any of the master styles then you simply write the new rules in the about.css. I’m just not clear on what the advantages of an ID on the body actually are. What am I missing here? Or perhaps I’m not aware of the drawback of the nested include system I use compared with the body ID method?
  12. Matt Wilcox

    1706 days ago

    Why the need for ASP? I’m assuming that wasn’t for the include, as CSS can include files without the need for any ASP/PHP parser. Dynamic style sheets perhaps? Anyway, back to the main point…

    I can imagine that for a website which has a small set of HTML pages to style the body-ID method might actually be neater, as long as you’re conscientious of keeping your CSS file arranged neatly. Once you start getting a larger number of ‘unique’ HTML pages however I’d be finding one mammoth CSS file something of a pain, and the include route might then be a nicer option. I suppose it depends on what you find neater – one very large CSS file, or a group of highly specific mini CSS files with one master file.

    Technically speaking I can only come up with two advantages to the body-ID approach. Firstly there’s a reduction of server hits, because you would only request one CSS file and not two. Secondly all the CSS for the entire site gets downloaded and cached on the very first visit, meaning loading any subsequent page wouldn’t need to re-download the CSS. Of course, if your website is a large one with many pages that turns into a problem rather than an advantage, as the first visit will seem slow because it’s pulling all the CSS for a lot of pages that might never get seen.
  13. Andrew

    1706 days ago

    I never knew it’s “whet your appetite
    how embarrassing ;-)

    good to see you promoting the optimisation of css, i get a strange buzz out of seeing well written, clean, commented code. am I weird?
  14. Payton

    1706 days ago

    Thanks! Great little tutorial; short and right to the point. I learned something new from your first point, I’ll be using this on my site. I see your second point a ton, too… it reminds me of a treehouse being built with different widths/lengths of wood; Hehe, maybe a bad analogy but thanks for the tutorial.
  15. Tom

    1706 days ago

    Classes are for generics, ID’s are unquies.

    Matt: give your body tag an ID.

    body#about { color: red; }
    body#folio { color: green; }

    John, sounds good but does the browser cache it?
  16. Matt Wilcox

    1706 days ago

    Tom – that’s my point, the ID tag on the body isn’t needed with the way I do things, and yet I achieve the same effect.

    I think John’s approach is better than mine for small sites with relatively few uniquely styled pages, but my approach is possibly better for larger sites with a large number of uniquely styled pages.
    The ‘single stylesheet and a body-ID’ Vs. ‘multiple stylesheet and CSS-includes’ matter is more about CSS organisation than it is about styling technique. You can do exactly the same things with both approaches, but there’s a point where one is more organised and efficient than the other – and that’s down to how many pages are getting uniquely styled.
  17. Graham Bancroft

    1706 days ago

    Thank you Sensei.
  18. Justin Reid

    1706 days ago

    John: You’re absolutely right. You can accomplish the same thing that I suggested by using a class on the body tag instead of on the wrappr div as I suggested. In fact, if might be better because you can control more elements on the page as it’s higher up in the page hierarchy.

    CMS: The company I’m at has it’s own CMS that it develops. We really only single out the homepage for this type of thing, and thus usually only ever add one class to the body/wrapper. However, when we have a need for more what we do is use a variable that denotes section name, and put that in as the class value. If you don’t have such a variable then I think a swtich statement would also work (but might get a big bloated or clumbsy). The switch would be performed on a template ID ( assumming each section has a unique template, which is rarely the case), or strip out the first folder off the root (for example “about” from “www.whatever.com/about/yada.php”).
  19. Matt Robin

    1706 days ago

    A good post John for other people who haven’t found out those useful aspects of CSS yet.
    These sorts of things were what I found most appealing about CSS when I first started with it a few years ago. If done properly – it can really save a lot of time and effort all round.

    Cutting down on classes, and making good use of IDs is certainly an effective way of tailoring the CSS to keep values constant on a site, and making minimal changes in the CSS rather than the HTML when needed.

    I’m hopeful that the ‘adjacent sibling selectors’ (ASS) fault in IE is remedied in IE 7….well, it would be nice!
  20. Jens Meiert

    1706 days ago

    Context, context, context. Every magician these days needs some context. For my German readers: Elegant code by contextual selectors
  21. Kev

    1705 days ago

    Nice article matey – however, its totally weirded out in Sage, making it hard to read. Not sure about other RSS readers so I don’t know if its just Sage or an issue with TXP’s XML generation.
  22. hink

    1705 days ago

    Wasn’t there a recent version of Opera that choked on body
    class and id attributes, or am I just smoking the houseplants again?

    I have badgered the guys on the IEblog about ASS, and thought nothing is 100% certain, chances are good that they will be functional.

    Frankly, I am not sure what I’ll do if they wack the * html {} bug—I might have to actually learn CSS. ;)
  23. John

    1705 days ago

    @ Kev
    Yes it is Sage…. it just breaks out of the box completely

    Something to do with how John marks up those code listings :)
  24. magicien

    1702 days ago

    Thanks for sharing