A featured navigation link stays teal even after `.featured { background-color: orange; }` is added. The existing `#main-nav a` rule also sets its background, and its selector wins on specificity. The browser compares specificity when earlier cascade criteria have not resolved a conflict; source order breaks a tie only after specificity is equal. section 1.1.3 section 1.1 section 1.1.4
Represent a selector’s specificity as three counts: IDs, classes, and tag names, in that order. Compare the counts from left to right. More IDs wins; if tied, more classes wins; if still tied, more tags wins. A single ID therefore outranks any number of classes. Selector length by itself does not determine the result. section 1.1.3
Table 1.1 Various selectors and their corresponding specificities
|
Selector
|
IDs
|
Classes
|
Tags
|
Notation
|
|---|---|---|---|---|
html body header h1
|
0
|
0
|
4
|
0,0,4
|
body header.page-header h1
|
0
|
1
|
3
|
0,1,3
|
.page-header .title
|
0
|
2
|
0
|
0,2,0
|
#page-title
|
1
|
0
|
0
|
1,0,0
|
Compare `html body header h1` (0,0,4), `.page-header .title` (0,2,0), and `#page-title` (1,0,0). The ID selector wins despite being shorter. section 1.1.3
For the teal navigation link, several fixes change which declaration wins, but they serve different reuse needs:
- `#main-nav .featured` adds an ID to the orange rule, making it more specific than `#main-nav a`. section 1.1.3
- `.nav a` and `.nav .featured` keep both rules within the navigation pattern; the latter has an extra class. This avoids relying on an ID to style every navigation link. section 1.1.3
- `.nav a` and `a.featured` have equal specificity, so the later declaration wins. But `a.featured` also matches links outside the navigation; there it may supply an orange background without the navigation link’s other button styles. section 1.1.4
Specificity is not the whole cascade. Stylesheet origin, inline styles, layers, and scope proximity also participate in precedence. Layers can express priority that selector counts alone do not: a lower-specificity rule may be the one you intend to win. Within a layer, `:where()` offers a way to keep selectors from becoming unnecessarily hard to override. section 1.1 section 8.1 section 8.3.2
Lower the base rule’s specificity
A general link rule, `a:any-link`, has specificity 0,1,1; `.button` has 0,1,0 and cannot override its conflicting link styles on specificity alone. Write the base selector as `a:where(:any-link)` instead. Because `:where()` contributes zero, the base rule becomes 0,0,1 and `.button` can win when both match. `:where(#login-form) input` similarly counts as 0,0,1, despite the ID inside `:where()`. section 8.1 section 8.3.2
Watch for specificity introduced indirectly. `:is()` takes its specificity from its highest-specificity argument. A nested rule using `&` is interpreted through `:is()`, so one high-specificity selector in a parent list can raise the specificity of a nested selector even when another branch matches the element. Prefer selectors whose priority reflects the intended styling relationship, rather than escalating specificity to fix each conflict. section 8.4.2 section 1.1.3 section 9.0





