We all know about how CSS works right?
Styles are inherited and cascade through the DOM to child elements.
We know that CSS rules referring to element IDs have a greater weight than classes and inline styles trump them again.
But how exactly does the browser work out which styles should win out when multiple CSS rules apply to an element?
That’s when CSS Specificity comes in
This is a bit complicated, but stick with it, it gets exciting!
There are four elements to the scoring hierarchy:
- Inline styles e.g. <p style=”color:blue”>
- ID selectors e.g. #header{ color:blue; }
- Class selectors e.g. .footer{ color:blue; }
- Elements and pseudo elements e.g. p{ color:blue; } or p:after{ color:blue; }
Each element in the document may have style attributes set by one or more of these methods. Each method of setting the style carries a different weight and the total weight of a particular style attribute determines whether it applies.
Weighty
The weights of each style application can be thought of as:
- Inline – 1000
- ID – 100
- Class – 10
- Element 1
So for example, the following style declaration:
#header .logo a.main{ color:blue; }
Would get the following score:
Inline – | ID – | Class – | Element |
0 | 1 | 2 | 1 |
Whereas a similar declaration on the same element:
#content #header a{ color:red; }
would get a higher score
Inline – | ID – | Class – | Element |
0 | 2 | 0 | 1 |
So this link would be red because 0201 is greater than 0121
Does that add up?
Sounds simple right? Well it’s not quite that straight forward.
You might expect that if you had 10 classes on an element that would trump an ID, but it doesn’t.
That’s because the weights aren’t added up numerically, they are concatenated in to a string which is used for comparison. So the scores above could be thought of as
“0.1.2.1” and “0.2.0.1”
and if you had a style declaration with 13 classes and one ID, that would be
“0.1.13.0”
This explains why an ID always trumps a class.
Win, lose or draw
What happens if two rules get the same score?
The latest declared rule wins.
!Important notice
Any style which uses the !important tag behaves as the top trump and will beat any other weighted style declarations.
It’s powerful, so be careful how you use it.
In practice
So what does this mean for us? Not a great deal, you’re never going to sit down and work out these scores but it should give you a better understanding of why your styles might be getting ignored.
It also demonstrates why it’s a good idea to avoid inline styles, because it’s really difficult to override them in the stylesheet.
Likewise, the !important tag is dangerous and should only be used when absolutely necessary to override inline styles.
Generally, trying to understand how your styles are cascading and working within a structured styling pattern will lead to sensible CSS rule sets which play together nicely.