CSS Specificity Calculator

Paste any CSS selector to get its (a, b, c) specificity score with a plain-English breakdown of every part — or compare two selectors to see which wins.

Advertisement

How specificity works

Every selector scores in three columns — (a, b, c) — compared left to right. An ID (#nav) fills column a; classes (.btn), attribute selectors ([type="text"]), and pseudo-classes (:hover) fill column b; type selectors (div) and pseudo-elements (::before) fill column c. One ID beats any number of classes: 1,0,0 always wins over 0,99,99.

The tricky parts

The universal selector * and combinators (>, +, ~, space) add nothing. :is(), :not(), and :has() inherit the specificity of their most specific argument — so :not(#menu) scores 1,0,0. :where() is always free at 0,0,0, and :nth-child(2n of .item) adds the specificity of its of selector on top of the pseudo-class itself.

FAQ

How is CSS specificity calculated?
Specificity is a three-column score (a, b, c): a counts ID selectors, b counts classes, attributes and pseudo-classes, c counts type selectors and pseudo-elements. Columns are compared left to right — a single ID beats any number of classes.
How do :is(), :not(), :has() and :where() count toward specificity?
:is(), :not() and :has() take the specificity of their most specific argument — e.g. :not(#a) scores 1,0,0. :where() is the exception: it always contributes zero, no matter what is inside.
Does !important count toward specificity?
No. !important is a separate mechanism that overrides normal specificity entirely. Likewise, inline style="..." attributes beat any selector, but neither is part of the (a, b, c) score.
Why isn't my CSS rule applying?
Usually another rule has higher specificity, or an equal-specificity rule comes later in source order. Other culprits: an inline style, an !important declaration, or cascade layers reordering precedence. Paste both selectors into the compare box above to see which wins.
Advertisement