The cascade is an algorithm that defines how to combine property values originating from different sources. It lies at the core of CSS, as emphasized by the name: Cascading Style Sheets.
Only CSS declarations, that is property/value pairs, participate in the cascade. This means that at-rules containing entities other than declarations, such as a @font-face
rule containing descriptors, don't participate in the cascade. In these case, only the at-rule as a whole participates in the cascade: here, the @font-face
identified by its font-family
descriptor. If several @font-face
rules with the same descriptor are defined, only the most appropriate @font-face
, as a whole, is considered.
While the declarations contained in most at-rules — such as those in @media
, @document
, or @supports
— participate in the cascade, declarations contained in @keyframes
don't. As with @font-face
, only the at-rule as a whole is selected via the cascade algorithm.
Finally, note that @import
and @charset
obey specific algorithms and aren't affected by the cascade algorithm.
The CSS cascade algorithm wants to select CSS declarations to set the correct value for CSS properties. CSS declarations originate from different origins:
Though style sheets come from these different origins, they overlap in scope: the cascade algorithm defines how they interact.
The cascading algorithm determines how to find the value to apply for each property for each document element.
!important
, and by their origin. The cascade is in ascending order, which means that !important
values from a user-defined style sheet have precedence over normal values originated from a user-agent style sheet: Origin | Importance | |
---|---|---|
1 | user agent | normal |
2 | user | normal |
3 | author | normal |
4 | CSS Animations | see below |
5 | author | !important |
6 | user | !important |
7 | user agent | !important |
CSS animations, using @keyframes
at-rules, define animations between states. Keyframes don't cascade, meaning that at any given time CSS takes values from only one single @keyframes
, and never mixes multiple ones together.
When several keyframes are appropriate, it chooses the latest defined in the most important document, but never combined all together.
Also note that values within @keyframes
at-rules overwrite all normal values but are overwritten by !important
values.
User-agent CSS:
li { margin-left: 10px }
Author CSS 1:
li { margin-left: 0 } /* This is a reset */
Author CSS 2:
@media screen { li { margin-left: 3px } } @media print { li { margin-left: 1px } }
User CSS:
.specific { margin-left: 1em }
HTML:
<ul> <li class="specific">1<sup>st</sup></li> <li>2<sup>nd</sup></li> </ul>
In this case, declarations inside li
and .specific
rules should apply. No declaration is marked as !important
, so the precedence order is author style sheets before user style sheets or user-agent stylesheet.
So three declarations are in competition:
margin-left: 0
margin-left: 3px
margin-left: 1px
The last one is ignored (on a screen), and the two first have the same selector, hence the same specificity: it is the last one that is then selected:
margin-left: 3px
Note that the declaration defined in the user CSS, though having a greater specifity, is not chosen as the cascade algorithm is applied before the specifity algorithm.
© 2005–2018 Mozilla Developer Network and individual contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Cascade