CSS tips and tricks, Part 1

As I stated in my recent article on CSS shorthand properties, I get a lot of questions about CSS from people who haven’t spent quite as much time working with CSS as I have. Their CSS is often not as efficient as it could be, and I come across some mistakes that are easy to make when you’re starting out with CSS.

Since I’ve been using CSS extensively for a couple of years I’ve picked up some tricks that either make the CSS more efficient or solve a specific problem. I’d like to share my favourite CSS tricks and explain some of the most common beginner’s mistakes (of which I’ve made several). If you’re experienced with CSS you’ll have seen most of these tips and tricks before, but who knows – maybe you can find one or two you haven’t seen before.

This was originally meant to be a single article, but the list of tips and tricks just kept on growing, so I’ve decided to split it into two parts for easier digestion.

Use CSS shorthand

To save space and make your CSS files easier to read I recommend using shorthand syntax to declare several properties in a single declaration. How the available shorthand properties are used is described in my article Efficient CSS with shorthand properties, so I’m referring you to that instead of going into any details here.

Specify a unit unless the value is 0

Not specifying a unit for length values is a very common mistake among CSS beginners. In HTML you can get away with that, but in CSS all length values must have a unit. There are two exceptions: line-height and 0 (zero) values. Note that the value must be immediately followed by the unit – do not insert a space between them.

There is no need to specify a unit for 0 (zero) values because zero pixels equals zero centimeters equals zero of any other length unit. Despite this it’s very common to see something like padding:0px where padding:0 would do.

While there’s nothing wrong with specifying a unit when the value is 0, it’s a waste of space and – at least to me – looks untidy.

Remember case sensitivity

When CSS is used with XHTML, element names in selectors are case sensitive. To avoid getting caught by this I recommend always using lowercase for element names in CSS selectors.

Values of the class and id attributes are case sensitive in both HTML and XHTML, so avoid mixed case for class and id names. If for some reason you do use mixed case, make doubly sure to match the case in your CSS with that in the markup.

Specifying colours

This tip is in the shorthand article mentioned earlier, but I use it so much I’ll repeat it here: in CSS, when you use hexadecimal colour notation and a colour is made up of three pairs of hexadecimal digits, you can write it in a more efficient way by omitting every second digit:

#000 is the same as #000000, #369 is the same as #336699.

And remember that octothorpe (#) before the colour code.

Another colour related tip is that you can specify web safe colours by using only digits that are multiples of 3 for the red, green, and blue values: 0, 3, 6, 9, C, and F. #99c is a web safe colour, #98c is not.

Eliminate element types for class and id selectors

When writing selectors that target an element with a certain class or id value, you can omit the element type before the . (class selector) or # (id selector).

So, instead of writing

  1. div#content { /* declarations */ }
  2. fieldset.details { /* declarations */ }

you can write

  1. #content { /* declarations */ }
  2. .details { /* declarations */ }

and save a few bytes for each selector.

This is especially useful for id selectors since they must be unique in a document, which reduces the risk of rules conflicting with each other. class names on the other hand can be used any number of times in a document, and different element types can be assigned the same class name (or names). To style element types with the same class name differently you will need to specify the element types in the selector.

Be aware that the above rules are not identical. If you write one rule with and one rule without the element type in the selector, the rule that uses the element type will have higher specificity.

Default values

You can often eliminate the need to specify a value for a property by taking advantage of that property’s default value. This is especially important to consider when you use shorthand properties, since any unset properties are assigned the default values of the corresponding individual property.

Some common default values are 0 for padding (though there are exceptions to this), and transparent for background-color.

Since there are slight differences in the default values between browsers, some people like doing a Global white space reset by zeroing both margin and padding for all elements at the top of their stylesheets:

  1. * {
  2. margin:0;
  3. padding:0;
  4. }

Don’t redeclare inherited values

The values of many properties are inherited by any descendants of the element that you specify the property for. color and the font related properties are the most common examples of such properties.

Be aware that some properties may be overridden by browser specific user agent style sheets, i.e. the browser’s defaults. That’s why you can’t make all headings non bold with the following rule:

  1. body { font-weight:normal; }

The browser’s predefined rules are more specific because of the cascade, which is described next.

Take advantage of the cascade

The cascade lets you use multiple rules to specify the properties for an element. You can either redefine the same property or define additional properties. Let’s say you have the following markup:

  1. <p class="update">Update: Lorem ipsum dolor set</p>

In the CSS, you can use separate rules to specify the properties that are common to all p elements and those that are specific to p elements with class="update":

  1. p {
  2. margin:1em 0;
  3. font-size:1em;
  4. color:#333;
  5. }
  6. .update {
  7. font-weight:bold;
  8. color:#600;
  9. }

The two rules will be combined for p elements with class="update". Since a class selector is more specific than a type selector, the properties defined in the second rule will be used when a conflict occurs, as for color in this case.

More info on how the specificity of CSS rules is calculated can be found in Calculating a selector’s specificity in the CSS 2.1 specification.

Multiple class names

You can assign multiple class names to an element. This allows you to write several rules that define different properties, and only apply them as needed. Let’s assume you’re marking up an image gallery that contains some images that are royalty free and some that are not. There may also be a special offer on some images. Here’s the markup for three images:

  1. <img src="foo.gif" class="special" alt="" />
  2. <img src="bar.gif" class="royaltyfree" alt="" />
  3. <img src="baz.gif" class="royaltyfree special" alt="" />

To style the images that are royalty free to make them differ from the others you can make a rule for elements that have a class name of royaltyfree, and if you want the images with a special offer to stand out a bit you can use the special class to make a CSS rule for that.

The CSS could then look something like this:

  1. .royaltyfree { border:2px solid #666; }
  2. .special {
  3. padding:2px;
  4. background:#ff0;
  5. }

Any images that have a class name of special will have a padding and a yellow background. Images that have a class name of royaltyfree will have a border, and those that have both class names will have a border, a padding, and a yellow background.

You can take this much further – this is just a simple example. And do try to use semantic class names that describe what an element is or does rather than what it looks like.

Use descendant selectors

Not using descendant selectors is one of the most common examples of inefficient CSS I see from novice CSS authors. Descendant selectors can help you eliminate many class attributes from your markup and make your CSS selectors much more efficient. Take the following code structure:

  1. <div id="subnav">
  2. <ul>
  3. <li class="subnavitem"><a href="#" class="subnavitem">Item 1</a></li>
  4. <li class="subnavitemselected"><a href="#" class="subnavitemselected">Item 1</a></li>
  5. <li class="subnavitem"><a href="#" class="subnavitem">Item 1</a></li>
  6. </ul>
  7. </div>

This could be accompanied by the following CSS:

  1. div#subnav ul { /* Some styling */ }
  2. div#subnav ul li.subnavitem { /* Some styling */ }
  3. div#subnav ul li.subnavitem a.subnavitem { /* Some styling */ }
  4. div#subnav ul li.subnavitemselected { /* Some styling */ }
  5. div#subnav ul li.subnavitemselected a.subnavitemselected { /* Some styling */ }

You could replace all of the above with this markup:

  1. <ul id="subnav">
  2. <li><a href="#">Item 1</a></li>
  3. <li class="sel"><a href="#">Item 1</a></li>
  4. <li><a href="#">Item 1</a></li>
  5. </ul>

and this CSS:

  1. #subnav { /* Some styling */ }
  2. #subnav li { /* Some styling */ }
  3. #subnav a { /* Some styling */ }
  4. #subnav .sel { /* Some styling */ }
  5. #subnav .sel a { /* Some styling */ }

Keep it as clean as possible and both your markup and your CSS will be more efficient and easier to read.

Avoid quoting URLs

To save a couple of bytes here and there, I avoid quoting the URLs for background images. Quoting isn’t necessary, and there have been reports of some browsers (most notably IE/Mac) having problems when URLs are surrounded by quotation marks.

To be continued

Did I miss your favourite CSS tip? Relax, there’s more to come in CSS tips and tricks, Part 2, out soon now.

Translations

This article has been translated into the following languages:

Posted on March 15, 2005 in CSS

Comments

  1. That was a great breakdown of some commonly used CSS tricks Roger. I’ll be providing that link to some friends that ask me about this quite often.

    Can’t wait for Part II, might have some super tips in there.

    ;)

  2. I think I read somewhere that the order of the declarations for links is important for Explorer.

    eg:

    a:link { /\* declarations \*/ }  
    a:hover { /\* declarations \*/ }  
    a:active { /\* declarations \*/ }  
    a:visited { /\* declarations \*/ }
    

    is different from:

    a:link { /\* declarations \*/ }  
    a:visited { /\* declarations \*/ }  
    a:active { /\* declarations \*/ }  
    a:hover { /\* declarations \*/ }
    

    Is this true (I have never noticed any problems) and, if so, can you elaborate on what the right order is?

  3. Harold, that’s the right order. Any rule may be over-written by following rules. So in the first example above, your “:hover” style will apply to all unvisited links, and in the second to all links, regardless of whether they have been visited.

    Nice article, Roger. I was of the opinion web-safe colours are not really important any more - can you elaborate on that? What sort of percentage (if it’s possible to tell) would have a problem with non-web-safe colours?

  4. Whoops. Should probably elaborate on which is the right order:

    :link :visited :active :hover

    That’s what I usually go for. Many people have :active and :hover the other way around, but that doesn’t make the world of difference.

  5. Your last tip about quoting urls was actually most useful for me as I had some confusion about quoting (or not) with regards to the @import directive and url() in stylesheets. I know there are some tables about which browser supports what, but a bigger writeup (hint ;)) would help end a lot of confusion.

    Great blog, I really enjoy your focus on writing your own articles, even if some things you write about are not new to me I still enjoy a good article much more then a uncomprehensible paragraph linking to other blogs :)

  6. March 15, 2005 by Roger Johansson (Author comment)

    Harold, Dave: The order for link states should be

    :link :visited :hover :active
    

    LoVe HAte (or whatever else you can think of to remember it). Eric Meyer explains this in Link Specificity.

  7. What a brilliant reminder of lots of things I should do but often don’t. More details about inheritance might be useful - I get loads of emails about that. I still think CSS inheritance confuses people, especially when they go back to edit the sheet. Sensible methods of annotating CSS might be a useful thing to cover.

  8. The order for link states that I’ve heard is

    :link :visited :focus :hover :active

    The ryhme to remember is: Lord Vaders Former Handle Anikin

    I seem to recall that the :focus was for the benefit of those (me) that navigate with the keyboard (tab/shift-tab).

  9. I find that sometimes its better to leave a few section in and remember what a rule was for. For example div#id can be usefull if your dealing with alot of ID’s though menus or forms.

    Still excellent tips, the websafe one is a jem.

  10. just wondering, how far back do browsers support the universal selector? *

  11. March 15, 2005 by Roger Johansson (Author comment)

    Dave: About web safe colours — I don’t pay much, if any, attention to them anymore. I just added that little tip anyway just in case it would come in handy for somebody.

  12. March 15, 2005 by Tobias Bergius

    Nice article!

    For part 2 you could add using the :focus psuedo-class—for navigation and stuff like that—along with :hover. Not all people uses a mouse.

  13. March 15, 2005 by Tobias Bergius

    Seems like your your blog doesn’t like em dash. :)

  14. March 15, 2005 by Simon

    Thank you very much for this article. I’m designing with CSS for about a half a year now and I’m still confused about several aspects of it. With your article you just helped to end some of that confusion. I’m eagerly waiting for your part 2.

  15. hey an how can I omitting every second digit: for this color: #CDCDCD ?

    ;)

  16. March 15, 2005 by Roger Johansson (Author comment)

    Tobias: I had to disable SmartyPants in comments and keep forgetting.

    RameX: You can’t because it isn’t made up of three pairs :-)

  17. March 15, 2005 by ghola

    Another great article, thank you Roger.

    I wonder where we should place a:focus? I always stick it with a:hover like this :

    a:hover, a:focus { /* declarations */}

  18. One word, octothorpe. I have never heard that before, but I will just take that as some high ranking CSS-guru terminology. Seriously, great article. I only wish I had seen something like this sooner in my CSS journey, as I have made many of these common mistakes.

    In the section: “Eliminate element types for class and id selectors”. I think the specificity should be explained a little further if this is to make any sense to a beginner CSSer. I remeber when I first started trying to write my selectors short-hand style (without the element) and I kept have specificity issues. Needless to say, I had no idea what the heck specificity was or how it worked.

    ghola, the :hover pseudo class is not the same as the :focus pseudo class. I would not recommend lumping them together. They are two different actions and should be differentiated as such. Take a look at these form fields, the :focus pseudo class is styled (the border changes) while the :hover pseudo class is not touched (there is not hover action on the field).

  19. To add… by these form fields, I mean the form on this page.

  20. March 15, 2005 by ghola

    Justin, I understand what focus is, I was enquiring specifically about a:focus and where it fits in the usual order of a pseudo classes, not how it applies to other elements.

  21. Sorry ghola, I have a knack for misinterpretting questions. It really depends on the effect you are trying to achieve. If you want elements that have focus to still be able to display the hover effect, then you put the :hover after the :focus. If you don’t, then you put the :focus last in your list of pseudo classes.

    Since all these pseudo classes have the same specificity, the order really determines the effect, and it boils down to what you are looking for.

  22. March 15, 2005 by Mordechai Peller

    Nice article.

    I think it’s worth noting that, specificity aside, in rare instances div#id and #id aren’t the same.

    As a stye sheet is meant to be used with multiple pages, it’s possible that the same id could be used with two different types of elements on two different pages.

    While, off hand, I can’t think of an instance where I would do this, since it’s legal and there may be an instance where it could be usefull, I thought I’d mention it.

  23. March 15, 2005 by xbhoff

    — Note that the value must be immediately followed by the unit – do not insert a space between them.

    why?

  24. Great article, Roger. I’ve got a bunch of friends that are trying to learn CSS, and, instead of teaching them, I can send them this article and continue to be lazy. Thanks for that.

    ghola and Justin: I haven’t had any problems with the pseudo classes. I’ve always heard Lord Vader Froze Hans’ Ass:

    :link :visited :focus :hover :active

    Any thoughts?

  25. March 15, 2005 by Roger Johansson (Author comment)

    xbhoff: Because ;-)

    From CSS 2.1, Syntax and basic data types:

    The format of a length value (denoted by <length> in this specification) is a <number> (with or without a decimal point) immediately followed by a unit identifier (e.g., px, em, etc.).

  26. Hi Dan, I haven’t had any problems with the pseudo classes either. I was just trying to make clear that the order of the pseudo classes determines the effect.

    LVFHA works if you want elements that have focus to still display hover behavior (not always desired). If you want the :focus effect to trump the :hover effect, then you want LVHFA or Lord Vader Has a Funky Ass

  27. March 15, 2005 by ghola

    Thank you justin. I hadn’t thought of the possibility to have different visual effects for a:hover and a:focus. I’ll play a bit with that.

    Dan: cool way of remembering it!

    By the way thanks Roger, for letting us hang out here.

  28. @ multiple classes: these are not meant to attach different rules to your element. In general classes have nothing to do with style whatsoever.

    Class defines a (sub) class of elements, a group of elements that have a slightly different function than others. Therefore they might have a specific appearance. Think of classnames as jobnames. Different jobs: different appearance (police officer), multiple jobs: combined appearance.

    Also see http://www.rikkertkoppes.com/thoughts/class-and-style

  29. March 15, 2005 by Roger Johansson (Author comment)

    ghola: My pleasure. The beer is in the fridge ;-)

    rikkert: Absolutely. That’s why I think my multiple classes example is not the best. I’ll replace it with a better one ASAP.

    Update: Done.

  30. As for leaving off the element names for IDs (#id) and CLASSes (.className), I actually tend to leave them off id but ON for a class. That way I can apply the same class name to multiple elements. Whereas I’m less likely to use an ID more than once (y’know, cuz you can only use one on a page!)

    Great article, btw.

  31. March 16, 2005 by Mika

    Nice article, thank you. How about you copying your code samples, it copies also line numbers although marking does not show that those are copied, is that how it should work? :)

  32. One great thing about this article is that it’s not just good for beginners - it’s also terrific for those of us who have a certain comfort level with CSS but want to take it to the next level. Well done, Roger!

  33. March 17, 2005 by Antti

    You saved my day! Thanks for the tips :)

  34. One problem that I ran into when designing Spread Firefox was that using :hover or :focus greatly slows down modern browsers like Firefox since every element actually supports those states.

    It’s important that if you only want to affect your links, that you target and isolate your :focus and :hover states appropriately.

    Otherwise, great article!

  35. March 20, 2005 by Roger Johansson (Author comment)

    Mika: The code examples are in ordered lists, and browsers seem to copy the item numbers as well. I’d say it’s a browser problem. They really should highlight the text that will be copied.

    Chris: I haven’t noticed any such slowdown. Are you referring to specifying just :hover, with no element name?

  36. Excellent article! I’m definitely looking forward to Part II :)

  37. I’m with Mr Snook on elements for class selectors, but I’d not considered leaving them off for IDs when it clearly makes big sense. Nice one!

  38. Great summing-up about CSS, Roger! I’ve been a fan of CSS for 4 years.

  39. March 31, 2005 by SteveC

    #000 is the same as #000000, #369 is the same as #336699.

    actually IE has a nack of putting #abc -> #000, it works with greys, but colours are a problem

  40. March 31, 2005 by Roger Johansson (Author comment)

    SteveC: I can’t remember running into that bug. Which versions of IE are affected?

  41. Thanks for the great article Roger, I’m gonna swith to shorthand.. you have me convinced. Slim is good

  42. May 10, 2005 by Rob Moore

    Tab-through fails to get beyond the “Comments” form textarea into which this message was entered. Is the any way around this (other than [shift]+[tab]) ?

  43. Hello,

    Thank you for this great article. Since few times I make some mistakes. Now, I’ll fix them with your articles.

    Added in bookmarks ;)

    Thanks again.

  44. June 10, 2005 by Roy

    I’ve encountered some problems with shorthand before…

    for example there was one instance I was making a grid, and I marked some rows to be bold by specifying a class with “font-weight: bold;”.

    But one cell in the row had an anchor tag inside it, and our anchor tags are styled by default with “font: 12px Arial;”

    Took me a while to figure out that the anchor’s style had been default set to “font-weight:normal;” and had thus overridden the row’s style.

    I like the shorthand,but I think one should make sure it won’t adversely affect other styles in the document.

    Really great article, BTW, learned some neat stuff. :D

    BTW again, your comment form doesn’t seem to like my url because it contains the term “sinfree”

  45. That’s just great - here I am struggling to track down all the info I can on the correct coding and exactly what all the features there are in CSS and how to use them properly, THEN I find some clever dick has produced all this shorthand nonesense!!!

    Seriously though, great article which as I keep going back to it I am sure I will learn a great deal from. BUT as a complete beginner in CSS and XHTML I am wary of trying to run before I can walk, although I will now be going back through the coding of my site (my first attempt at using CSS btw) to see what mistakes I have already made!

  46. For educational purposes, you could use “alt” attributes on images (“royaltyfree” example), Roger ;)

  47. July 31, 2005 by Roger Johansson (Author comment)

    Roy: Sorry about the comment problem. Blame the spammers.

    Jens: Hmm. I’ve spent a couple of minutes trying to figure out what you mean, and I have no idea. Was that comment meant for another post? Or maybe it’s me being slow (not unheard of ;-) ).

  48. I’ve spent a couple of minutes trying to figure out what you mean, and I have no idea.

    <img src="foo.gif" class="special" />  
    <img src="bar.gif" class="royaltyfree" />  
    <img src="baz.gif" class="royaltyfree special" />
    

    All without any “alt” attribute…

  49. Gah. Once again, this is the example I referred to:

    &lt;img src="foo.gif" class="special" /&gt;
    &lt;img src="bar.gif" class="royaltyfree" /&gt;
    &lt;img src="baz.gif" class="royaltyfree special" /&gt;
    
  50. August 3, 2005 by Roger Johansson (Author comment)

    Jens: Doh! So obvious I just couldn’t see it. Thanks for alerting me :-)

  51. No problem ;)

  52. I use some css on our site, but is it possible to “turn off” css in certain places on the pages?

    For example:

    I have the links in the nav bar css’ed, but all the links on the paged use the same css rule. I want to “disable” css on the rest of the page…

  53. May 7, 2006 by Michael B

    Some one asked how to get CDCDCD into shorthand, well you could try rounding. CDCDCD is almost the same as DDDDDD which is DDD. Take each two numbers/letters and look at the second one and if it is between 0-8 leave the first alown if is is between 9-F round it up. Do this for each of the three pairs. The color will be almost the same. This dose not work for all colors, like efefef is a light gray but if rounded if becomes fff which is white.

Comments are disabled for this post (read why), but if you have spotted an error or have additional info that you think should be in this post, feel free to contact me.