Asking for a Friend: CSS Sorting
What is the Cascade?
The cascade is a mechanism for determining which styles should be applied to a given element, based on the rules that have cascaded down from various sources.
The cascade takes importance, origin, specificity, and source order of style rules into account. It assigns a weight to each rule. When multiple rules apply to a given element, the rule with the greatest weight takes precedence. The result is an unambiguous way to determine the value of a given element/property combination.
Browsers apply the following sorting logic:
- Find all declarations that apply to a given element/property combination, for the target
media
type. - Sort declarations according to their importance (normal or important) and origin (author, user, or user agent).
From highest to lowest precedence:
- user
!important
declarations - author
!important
declarations - author normal declarations
- user normal declarations
- user agent declarations
- user
- If declarations have the same importance and source, sort them by selector specificity.
- Finally, if declarations have the same importance, source, and specificity, sort them by the order they are specified in the CSS. The last declaration wins.
So What is Specificity?
Specificity is a method of conflict resolution within the cascade.
Specificity is calculated in a very particular way, based on the values of 4 distinct categories. For explanatory purposes, the CSS2 spec represents these categories using the letters a
, b
, c
, and d
. Each has a value of 0
by default.
a
is equal to1
if the declaration comes from astyle
attribute in the HTML (“inline styles”) rather than a CSS rule with a selector.b
is equal to the number of ID attributes in a selector.c
is equal to the number of other attributes and pseudo-classes in a selector.d
is equal to the number of elements and pseudo-elements in a selector.
The specificity is given by concatenating all 4 resulting numbers. More specific selectors take precedence over less specific ones.
For example, the selector #id .class[href] element:hover
contains:
- One ID (
b
is1
) - One class, one attribute selector, and one pseudo-class (
c
is3
) - One element (
d
is1
)
Therefore, it has a specificity of 0,1,3,1
. Note that a selector containing a single ID (0,1,0,0
) will have a higher specificity than one containing any number of other attributes or elements (e.g., 0,0,10,20
). This is one of the reasons why many modern CSS architectural patterns avoid using IDs for styling purposes.
Then What is Inheritance?
Inheritance is distinct from the cascade and involves the DOM tree.
Inheritance is the process by which elements inherit the the values of properties from their ancestors in the DOM tree. Some properties, e.g. color
, are automatically inherited by the children of the element to which they are applied. Each property defines whether it will be automatically inherited.
The inherit
value can be set for any property and will force a given element to inherit its parent element’s property value, even if the property is not normally inherited.
Lastly, Using !important
The above should make it apparent that !important
is a separate concept to specificity. It has no effect on the specificity of a rule’s selector.
An !important
declaration has a greater precedence than a normal declaration (see the previously mentioned cascade sorting logic), even declarations contained in an element’s style
attribute.