The Importance of Being Specific
Written by Arron Gibson   

The Brass Tax

CSS is an emerging language, as such there are many theories regarding best practices for its implementation. Many coders will use browser specific hacks to achieve the desired results or will break down and resort to tables, which they may be familiar with. It has been my experience that these practices often create more work that could have been avoided by the designer or coder simply having a better understanding of how to properly implement CSS. One of the finer concepts to grasp in CSS is specificity.

Specificity is the weight given to CSS selectors and their level of importance. A more specific CSS selector will take precedence over a less specific selector. Perhaps an example:

Let’s Take the following XHTML fragment

<div id="halfMoon">
<p class="algernon">And, speaking of the science of Life, have you got the cucumber sandwiches cut for Lady Bracknell?</p>
</div>

Let’s now apply some CSS to this fragment:

p {color:red;}
p {color:blue;}

This CSS will effect a color change upon the paragraph text, setting it to blue. This is because the two selectors have the same specificity. When the same XHTML element is addressed with two separate CSS commands with the same specificity the later command will takeover and cancel out the previous command.

div p {color:red;} /* Specificity: 002 */
p {color:blue;} /* Specificity: 001 */

This code will make the paragraph red. Even though the blue command comes after the red command the red command is more specific and therefore takes preference. The /* Specificity */ comments are to indicate the selector’s specificity ranking. Here is the way a rank is given.

For each element in the selector (EX: p, img, div, ul, li (and so on)) that is to say each straight XHTML element, as in a tag, a ranking of 1 is given.

For each class declaration in the selector, marked by a period preceding (.algernon), a ranking of 10 is given.

For each ID declaration in the selector, marked by a pound sign preceding (#halfMoon) a ranking of 100 is given.

All of these scores are added together to give the selector an integer ranking. The higher the ranking the more importance is given to the rules that follow in the brackets after the selector { }.

examine the following:

.algernon {color:red;} /* Specificity: 10 */
html body div p {color:blue;} /* Specificity:1+1+1+1=4 */

The 1st rule takes effect. A rule of thumb to work with is that one class in the selector is enough to override any selector that is comprised only of elements. One ID selector is enough to override any selector that does not include ID selectors in most cases. In extreme cases where more than 9 classed elements are used in the selector the single ID selector will be less specific. This is really only theoretical however, in real world applications one would never run into a selector like that. especially if one follows my rules for best practices.

Best Practices:

All of what is above is simply part of the CSS 2.1 specification. What is to follow may be hotly contested and is simply my own thoughts on the workflow that serves me well.

KISS:

Keep It Shortly Specific: Remember that a single ID selector will outweigh many class selectors. Try to use the shortest possible selector for any given rule. why use div#container div#content p span.notice when most likely just .notice will suffice? that way when you have one off elements that need overrides to their styles, it’s easy to make a selector that is more specific.

Who’s body is this?

I always add a specific ID to my body tags (or a class to my container div if working in an environment where the body tag is generated for you and you can’t affect its parameters). This way if you have to edit anything on a certain page you can simply add the body ID to the front of any existing selector to override it. An ID added to a selector adds 100 specificity points to a selector. There are only 2 style conditions that add more weight than an ID. Inline styles and the !important statement.

You’re Out Of Line!!!

Here’s an example of an inline style:

<div id="halfMoon">
<p class="algernon">And, speaking of the science of Life, have you got the <span style="color:green;">cucumber sandwiches</span> cut for Lady Bracknell?</p>
</div>

inline styles are coded straight into the html using the "style" parameter in any XHTML element. This is a specific type of selector in that it is inherently selecting the element which it is coded into. It is given a weight of 1000 specificity points. meaning that the only thing that would outweigh an inline style would be either 10 hierarchical ID selectors (Ex: #page_1 #containerOuter #containerInner #contentBody #half_moon… but as you can see by the fact that I barely was able to come up with 5 nested IDs it is quite the rare situation when your inline styled element has 10 parent elements all with explicit and unique ID parameters.) or, and now we come to the beast of the article the mother of them all, the !important statement.

The Importance of Being Specific

the !important statement is not a selector but rather a rule. Let’s review the following code:

div#halfMoon p.algernon {color:red;} /* Selector Specificity: 112 (1 ID = 100 + 1 class = 10 + 2 elements = 2) */
p {color:blue !important;}
/* Selector Specificity: 1 (1 element = 1) */

The 2nd rule will take effect even though the other selector outweighs it by 111 points. Simply put the !important statement is the CSS beat stick. You can use it to completely negate the effects of specificity. Anything with an !important statement will take effect over anything without one. The ONLY way to counter the effects of the statement is to use it in a new rule with a higher ranking selector. Altering our previous code we can see this is action

div#halfMoon p.algernon {color:red !important;} /* Selector Specificity: 112 (1 ID = 100 + 1 class = 10 + 2 elements = 2) */
p {color:blue !important;}
/* Selector Specificity: 1 (1 element = 1) */

Now the 1st rule will take effect because they BOTH have the !important statement but the selector of the 1st rule is more specific. This can be a very important weapon in your CSS arsenal. But like with any weapon of mass destruction we must use it carefully. Many feel the tendency to use this rule willy nilly. The problem is that once you use it, the only way to beat it is to fight fire with fire. This is where the importance of being specific comes into play. if you can outweigh an existing CSS rule using a more specific selector, do so. Falling into the !important trap can get you into a lot of trouble, especially on larger projects or when working with teams. Eventually you end up with a style sheet full of !important statements and the only options you have are to continue the vicious cycle or to scrap them all and start from scratch evaluating which are actually needed and which can be replaced by using more specific selectors.

I always comment in my style sheet whenever I have used an !important statement stating why I had to use such grievous force and what I was attempting to do. Also remember that because specificity of the selector goes right out the window try to remember to be as specific as you can when using the !i bomb. I know that this goes against what I said earlier, about how general is better. However when wielding a force as formidable as this statement you can’t in good conscience just lob it at anything you like. Going back to our last XHTML snippet.

<div id="halfMoon">
<p class="algernon">And, speaking of the science of Life, have you got the <span style="color:green;">cucumber sandwiches</span> cut for Lady Bracknell?</p>
</div>

Say you were to think to yourself. "I know cucumber sandwiches are green!!! I don’t need some YAHOO content writer making my mind up for me!!!" you could write this and be done with it:

p span {color:black !important;}

That would indeed make the color black once more. However let’s say you have another span in another paragraph (a likely story). Even if you can very specifically target that new span using IDs and classes and nested elements you’re going to have to still use the !i bomb again because they’re still a span in a paragraph and therefore still effected by the code above. if we re-write this however to be:

div#halfMoon p.algernon span {color:black !important;}

We are still achieving the same result but with less ‘collateral damage’ this is!important to say the least.

All this writing is making me hungry. Somebody pass the cucumber sandwiches.

 
© 2012 Infinity Media Services Inc.