How to use CSS specificity

If you plan to use CSS on a regular basis you need to develop an understanding of what specificity is and how it is applied.

Other than floats and positions, specificity may be one of the hardest things to get used to, let alone master. The selectors you use in your CSS all have different weights and those are controlled by specificity. That’s why sometimes, when you apply a rule to an element, it isn’t reflected in your design.

If you’ve ever relied on the dreaded !important keyword to hack your CSS, then this article is for you.

How a browser reads CSS

To get your foundations solid, you need know how the browser actually reads CSS and how rules are overridden.

Firstly the browser will read a stylesheet from top to bottom meaning that with this code:

/*Line 10*/
ul li a {
color: red;
}

/*Line 90*/
ul li a {
color: blue;
}

The rule you specified at line 10 will get overridden and that anchor tag will be blue because the browser will consider rules further down your CSS to hold a greater priority.

This also works with the actual order you import your css files , for example:

<link href='css/style.css' rel='stylesheet'>
<link href='css/custom.css' rel='stylesheet'>

Since you placed the custom.css after the the style.css anything you write in the style.css (discounting for now, the weight of selectors ) will get overridden and substituted for what is in the custom.css, this technique is often used by theme creators to give the user some room to add their own styles without changing the main file. (Note however that custom.css doesn’t replace style.css entirely, only those rules that are specifically overridden will be replaced.)

Specificity

Everything above only applies if you are using the same weight on every selector. If you’re specifying IDs, classes or stacking elements then you’re giving them weight, and that is specificity.

There are four categories that define the specificity level of a selector: inline styles (these ones are sometimes used by javascript), ID’s, Classes and elements. How to measure specificity? Specificity is measured in points, with the highest points value being applied.

  • ID’s are worth a 100 points.
  • Classes are worth 10 points.
  • Elements are worth 1 point.

Knowing this, if you use a selector like so:

#content .sidebar .module li a

Its total weight is 122 points ( 100 + 10 + 10 + 1 +1 ), which is an ID, two classes and two elements.

Things to remember

  • ID’s have way too much weight compared to classes and elements so you should limit the use of ID’s in your stylesheets to the bare minimum.
  • In cases where the selectors have the same weight the order they appear is reverted to, the latter being the higher priority.
  • Styles embedded in your HTML trump styles in stylesheets, because they are closer to the element.
  • The only way to override inline styles is to use the !important statement.
  • Pseudo classes and attributes have the same weight as normal classes.
  • Pseudo elements also have the same weight as a normal element.
  • The universal selector (*) holds no weight.

Examples

ul li a {
color: red;
}

This selector will hold a weight of 3 , which means that just by adding a class somewhere else, you can override it.

.content #sidebar {
width: 30%;
}

This selector has a weight of 110 points mainly because of the ID that adds 100 points of the 110 total.

.post p:first-letter {
font-size: 16px;
}

This selector has a weight of 12 points ,since the pseudo-element :first-letter only weighs 1 point and so does the p tag.

p {
font-family: Helvetica, arial, sans-serif;
}

This selector only weighs 1 point , this type of selector should be used at the top of the page when you marking the basic styles that later on may be overridden for specific areas.

Always bear in mind that to override an ID selector you have to write 256 classes for the same element , like so:

#title {
font-weight: bold;
}

.home .page .content .main .posts .post .post-content .headline-area .wrapper /* ... etc. ... */ .title {
font-weight: normal;
}

Only this way will the second selector beat the one using the ID.

Conclusion

Specificity isn’t a flashy aspect of CSS, but in my opinion it’s the area most overlooked. Getting your specificity right not only helps you avoid bugs, but it will speed up both your development and your final site.

Do you overuse IDs when writing CSS? Do you ever fall back on !important? Let us know in the comments.

Featured image/thumbnail, precision image via Shutterstock.

Sara Vieira

Sara Vieira

Sara Vieira is a freelance Web Designer and Developer with a passion for HTML5/CSS3 and jQuery. You can follow her on twitter or check out her website.

Join to our thriving community of like-minded creatives!