ToolJutsu
All tools
Developer Tools

CSS Specificity Calculator

Calculate the specificity of any CSS selector.

Specificity is read as (a, b, c): a = IDs, b = classes, attributes and pseudo-classes, c = elements and pseudo-elements. Separate multiple selectors with commas.

Compare two selectors
Processed on your device. We never see your files.

How to use CSS Specificity Calculator

What this tool does

This calculator works out the specificity of a CSS selector — the value the browser uses to decide which rule wins when several rules target the same element. It parses the selector you type, identifies every component (IDs, classes, attributes, pseudo-classes, elements and pseudo-elements), and produces the standard (a, b, c) triple. It also explains what contributed each point, so you can see exactly why a selector is as strong as it is. It handles comma-separated selector lists, the functional pseudo-classes :not(), :is() and :has(), and the always-zero :where(). Everything runs in your browser.

Why you might need it

Specificity is the single most common reason a CSS rule “doesn’t work.” You write a style, it has no effect, and the cause is another selector elsewhere that the browser considers more specific. Reading specificity by eye is error-prone, especially once :not() and :is() are involved, because their rules are not obvious. Calculating it precisely turns a guessing game into a fact: you can see whether your new rule will actually override the old one, and if not, by how much you would need to strengthen it. It is also a great teaching aid — the per-component breakdown makes the abstract rules concrete.

How to use it

  1. Type or paste a CSS selector into the input — for example #nav ul.menu li:hover a::before.
  2. Read the (a, b, c) triple shown next to it, colour-coded by column.
  3. Review the breakdown beneath: each line names a component and the column it added to.
  4. To analyse several selectors at once, separate them with commas — each is scored on its own line.
  5. To settle a conflict, type the two competing selectors into the Compare fields and the tool tells you which one wins.

Common pitfalls

The biggest surprise is the functional pseudo-classes. :not(), :is() and :has() are transparent: they take on the specificity of their most specific argument, and the keyword itself counts for nothing. So :is(#main, .side) adds (1,0,0) — the ID, not a pseudo-class. :where() is different again: it always contributes (0,0,0), which is exactly why it is useful for low-specificity base styles. Another trap is the universal selector * and combinators (>, +, ~, and the descendant space): they add nothing at all. And remember that the columns do not “carry” — (0,1,11) still loses to (0,2,0), because b is compared before c.

Examples

#header is (1,0,0). .btn.btn-primary is (0,2,0) — two classes. a:hover is (0,1,1) — one pseudo-class, one element. ul li::marker is (0,0,3) — two elements and one pseudo-element. :where(.a, #b) p is (0,0,1) — the :where() part is wiped to zero, leaving only the p. The longer #nav ul.menu li:hover a::before is (1,2,4) — one ID, one class plus the :hover pseudo-class, and three element types plus the ::before pseudo-element.

Tips and advanced use

When a style refuses to apply, paste both selectors into the compare boxes before you reach for !important — often a small, well-placed class is enough to win cleanly. If you are designing a component library, lean on :where() to keep base styles at zero specificity so consumers can override them without a fight. And because the selector is analysed locally, you can paste selectors from any private stylesheet without it leaving your machine.

Frequently asked questions

What do the three numbers in specificity mean?
Specificity is written as a triple (a, b, c). The 'a' column counts ID selectors, the 'b' column counts classes, attribute selectors and pseudo-classes, and the 'c' column counts element types and pseudo-elements. They are compared left to right, so any value in 'a' beats any amount of 'b'.
Why does my :not() not add to the count?
The :not(), :is() and :has() pseudo-classes are transparent — they contribute the specificity of their most specific argument, and the pseudo-class itself counts for nothing. So :not(.active) adds one class, not a class plus a pseudo-class.
Does :where() ever add specificity?
No. The :where() pseudo-class always contributes zero, no matter what is inside it. It exists specifically so you can group selectors without raising their specificity, which makes the resulting rules easy to override.
Is my selector sent anywhere?
No. The selector is parsed by JavaScript running in your browser. Nothing is uploaded, so you can safely analyse selectors from private or unreleased stylesheets.
What happens when two selectors have equal specificity?
When specificity ties, the rule that appears later in the stylesheet wins. The compare feature reports a tie in that case so you know source order is what decides the outcome.

Related tools