Pattern: Confusing CSS prioritization
Issue: -
Source order is important in CSS, and when two selectors have the same specificity, the one that occurs last will take priority. However, the situation is different when one of the selectors has a higher specificity. In that case, source order does not matter: the selector with higher specificity will win out even if it comes first.
The clashes of these two mechanisms for prioritization, source order and specificity, can cause some confusion when reading stylesheets. If a selector with higher specificity comes before the selector it overrides, we have to think harder to understand it, because it violates the source order expectation. Stylesheets are most legible when overriding selectors always come after the selectors they override. That way both mechanisms, source order and specificity, work together nicely.
This rule enforces that practice as best it can. (It cannot catch every actual overriding selector (because it does not know the DOM structure, for one), but it can catch certain common mistakes.)
The following patterns are considered violations:
#container a { top: 10px; } a { top: 0; }
/** ↑ ↑
* The order of these selectors represents descending specificity */
b a {}
a {}
a + a {}
a {}
b > a[foo] {}
a[foo] {}
a {
& > b {}
}
b {}
@media print {
#c a {}
a {}
}
The following patterns are not considered violations:
a {}
b a {}
a {}
a + a {}
a[foo] {}
b > a[foo] {}
b {}
a {
& > b {}
}
a::before {}
a:hover::before {}
a {}
a:hover {}
@media print {
a {}
#c a {}
}
a {}
@media print {
#baz a {}
}