Author: Stefano Frasca
The Cascade is a fundamental element of CSS: it means that in order to fully understand how an element will be rendered, a developer should be aware of how weight, specificity, and order will affect the process.
In presence of multiple rules competing for the styling of an element, the browser chooses which one to use using a combination of how the rule was defined (with classes, id, HTML elements), and where (inline, internal style, external style, browser default, etc.).
Weight and Specificity
Given a CSS selector we can calculate the specificity by giving a weight to each element that is included in the selector itself:
- X – inline style attributes
- A – number of ID’s in the selector
- B – number of other attribute selectors, class selectors and pseudo-classes
- C – number of element names
Specificity is given by concatenating X.A.B.C where X has much more weight than A, A has much more weight than B, and so on. Some examples:
1 2 3 4 5 6 7 8 9 10 11 |
p a {...} /* specificity: 0.0.0.2 */ p.blue a {...} /* specificity: 0.0.1.2 */ .blue .link {...} /* specificity: 0.0.2.0 */ #sel .link {...} /* specificity: 0.1.1.0 */ /* inline <a style="..." href="..."></a> specificity: 1.0.0.0 */ |
N.B.: as mentioned before, #id selectors have a higher weight than attribute selectors. So #sel
> [id='sel']
Criteria Order
Starting from the most important to the least important, there is an order which the browsers follow to choose which CSS rule to use for rendering an element.
!important
This rule cancels all other criteria. Using it in the description of a CSS rule forces the use of such rule.
1 2 3 4 5 6 7 8 |
p { color: red !important; } #el { color: green; } /* <p id="el">TEST<p> */ /* TEST will be RED and not GREEN */ |
CSS Directive
These directives define whether the style sheet or the individual rules must be applied to certain media (screen, print, TV, braille, etc …). These have priority over all other criteria below.
Origin
Stylesheet file origin is important: the document stylesheet is evaluated first, then the user defaults (user profile in the browser), and finally the browser default stylesheets.
Libraries such as Reset and Normalize are useful for bypassing or minimizing the impact of this directive.
Specificity
This is the criteria explained in section above.
Position
If until nowe two CSS rules have the same weight, then the one specified last wins. In a canonical HTML, where most external styles are declared in the head and some (hopefully a few!) styles are inline in the body, then those declared last will have precedence.
Best Practices
These are some tips to write good CSS code by mitigating the effect of rule specificity and therefore the cascading chain.
- DON’T use IDs in CSS – no reuse, high specificity that even nested classes cannot exceed
- No nest selectors – if
.navigation-list a {}
works, don’t usenav .navigation-list a {}
- Not characterize selector – if
ul li a {}
work, don’t useul.navigation li a {}
if you don’t need it - USE classes: high reuse, high portability, low and proportional (to numbers) specificity
- Avoid !important: since
!important
is at the top of the selection criteria, an !important rule can be overwritten only by another !important. This way we would have a style sheet where no style is important and all styles are important. Frustrating!
I hope this overview and these hints have clarified to you how important cascading is in the management of CSS. To the next article!
Bonus: if you are a Star Wars fan you MUST read this article by @malarkey about Sith power specificity!!! Awesome!