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.


This article has been translated into the following languages:

Posted on March 15, 2005 in CSS