SpecificitySelectors Level 4
CSS specificity calculator
See the (a, b, c) weight of every selector, part by part, and find out why one rule beats another.
Selectors
Columns: ID selectors, classes, attributes and pseudo-classes, types and pseudo-elements.
Specificity
7 selectors#nav .item > a:hover121#navID.itemclassatype:hoverpseudo-class
.menu li a012.menuclasslitypeatype
:is(#main, .content) p101:is(#main, .content)pseudo-class (1, 0, 0)ptype
- :is() counts as its most specific argument (1, 0, 0); the pseudo-class itself adds nothing.
:where(.card) .title010:where(.card)pseudo-class (0, 0, 0).titleclass
- :where() always adds zero, whatever is inside.
li:nth-child(2n+1 of .featured)021litype:nth-child(2n+1 of .featured)pseudo-class (0, 2, 0)
- A pseudo-class (0, 1, 0) plus its most specific “of” selector (0, 1, 0).
a::before002atype::beforepseudo-element
input[type="email" i]:focus-visible021inputtype[type="email" i]attribute:focus-visiblepseudo-class
Which one wins?
A wins. A is (1, 0, 1), B is (0, 3, 1). (1, 0, 1) beats (0, 3, 1): it has more ID selectors (1 vs 0). Columns are compared left to right and the first difference decides, so the loser's bigger numbers further right never catch up.
How specificity is counted
When two rules set the same property on an element, the browser first compares origin, importance, cascade layers and scope, and only then specificity. Specificity is three counts compared left to right: IDs, then classes, attributes and pseudo-classes, then type selectors and pseudo-elements. The universal selector and combinators add nothing.
- :is(), :not() and :has() count as their most specific argument; the pseudo-class itself adds nothing.
- :where() always counts as zero, which makes it handy for low-priority defaults.
- :nth-child(An+B of S) counts as one pseudo-class plus the most specific selector in S.
- Legacy pseudo-elements like
:beforecount as pseudo-elements, not pseudo-classes. - & in nested CSS takes the specificity of the parent selector list, which a single line cannot know, so it is shown as zero with a note.
Specificity questions
Do eleven classes beat one ID?
No. The columns never carry over: (1, 0, 0) beats (0, 11, 0) and any number of classes. The old “add up the points” explanation is wrong.
Where do inline styles and !important fit?
They are decided before specificity. A style attribute beats any selector, and an !important declaration beats normal ones regardless of specificity. Cascade layers are also compared first.
How do I lower the specificity of a selector?
Wrap parts of it in :where(), replace IDs with classes, or move base styles into an earlier cascade layer so later rules win without stacking selectors.