CSS Specificity Calculator

Paste a CSS selector and see its specificity broken down as (a, b, c) — IDs, then classes/attributes/pseudo-classes, then element types and pseudo-elements — with a tag for every piece showing what it added. Enter several selectors and the one that wins the cascade is highlighted. The calculator handles the tricky cases too: :is() and :not() take the specificity of their most specific argument, and :where() contributes nothing. Runs entirely in your browser.

How to use the CSS Specificity Calculator

Type or paste one selector per line. Each is scored instantly as a specificity triple (a, b, c): a counts ID selectors, b counts classes, attribute selectors, and pseudo-classes, and c counts element types and pseudo-elements. Below each score, a row of tags shows every simple selector and exactly how much it contributed — so you can see why #nav adds to the first number while .active adds to the second. When you enter more than one selector, the calculator marks the winner: the one a browser would apply if they all targeted the same element.

It understands the modern selectors that trip people up. :is(…), :matches(…), :not(…), and :has(…) take the specificity of their most specific argument rather than counting as a single pseudo-class. :where(…) always contributes zero, which is what makes it useful for low-priority defaults. Double-colon pseudo-elements like ::before count as type-level, and the universal selector * and combinators (>, +, ~, descendant space) add nothing, as the spec requires.

How CSS specificity decides the winner

When two CSS rules set the same property on the same element, the browser needs a tiebreaker. That tiebreaker is specificity: a measure of how precisely a selector targets an element. It's calculated as three numbers, conventionally written (a, b, c). The first counts ID selectors, the second counts classes, attribute selectors, and pseudo-classes, and the third counts element types and pseudo-elements. The numbers are compared left to right like version numbers — any selector with a higher a beats every selector with a lower a, regardless of the other columns — so a single ID outranks any number of classes, and a single class outranks any number of element selectors.

Specificity is only one layer of the cascade, and knowing where it sits prevents a lot of confusion. Inline style attributes rank above any selector, and !important declarations override normal ones entirely, sitting outside the (a, b, c) comparison. When two selectors have identical specificity, the last one in source order wins — which is why the order of rules in a stylesheet matters. The universal selector and combinators don't change specificity at all; they affect what a selector matches, not how strongly it matches.

Understanding specificity is the cure for the most common CSS frustration: "why isn't my style applying?" Usually the answer is that another rule is more specific, and the fix is to either match that specificity or restructure so you don't have to. This is also why over-qualified selectors and ID-based styling cause maintenance pain — they raise specificity so high that later, more logical rules can't override them without escalating further. Methodologies like BEM and utility-first CSS exist largely to keep specificity flat and predictable, and newer tools like :where() and cascade layers give authors explicit control over these priority battles.

Common use cases

  • Debugging overrides. Work out why one rule beats another when a style won't apply.
  • Refactoring CSS. Spot over-specific selectors that make a stylesheet hard to override.
  • Comparing selectors. Check which of several candidate selectors will win the cascade.
  • Learning the cascade. See the (a, b, c) breakdown to build intuition for how specificity works.

Frequently asked questions

What do the three numbers mean?

They are (a, b, c): a is the number of ID selectors, b is the number of classes, attribute selectors, and pseudo-classes, and c is the number of element types and pseudo-elements. They are compared left to right, so a higher a always wins regardless of b and c.

How are :is(), :not(), and :where() handled?

The specificity of :is(), :matches(), :not(), and :has() equals that of their most specific argument — so :is(.a, #b) contributes (1,0,0). :where() always contributes zero, which is exactly what makes it useful for setting easily-overridden defaults.

Do !important and inline styles count?

They sit outside the (a, b, c) calculation. Inline style attributes rank above any selector, and !important overrides normal declarations entirely. This tool scores the selector itself; remember those two layers rank higher in the cascade.

Why does it say a selector "wins"?

When you enter multiple selectors, it highlights the one with the highest specificity — the rule a browser would apply if they all targeted the same element. If two tie, the one later in source order wins, as the cascade dictates.

Does the universal selector or combinators add specificity?

No. The universal selector * and combinators (>, +, ~, and the descendant space) contribute nothing to specificity. They change which elements a selector matches, not how strongly it matches them.
Embed this tool on your site

Free to embed, no attribution required (but appreciated). Paste this where you want the tool to appear: