Productivity and Utilities

CSS Specificity Calculator

Paste one selector per line to see its specificity score and which selector wins the cascade.

Your numbers

A line with commas is treated as a list, and each selector in it is scored on its own. Rule bodies in braces are ignored.

Result

Highest specificity

1,1,1

a[href^="https"]:not(.ext, #skip)

Selectors scored
8
Highest
a[href^="https"]:not(.ext, #skip)
Lowest
a

Specificity (IDs, classes, types)

SelectorIDsClasses, attributes, pseudo-classesTypes, pseudo-elementsScore
a0010,0,1
ul li0020,0,2
li.red.level0210,2,1
#x34y1001,0,0
#s12:not(p)1011,0,1
:is(em, #foo)1001,0,0
.card:where(.a, #b) > a:hover::before0220,2,2
a[href^="https"]:not(.ext, #skip)1111,1,1
How this was calculated
  1. IDs (#name) add to the first number. Classes (.name), attribute selectors ([x]) and pseudo-classes (:hover) add to the second. Type selectors (div) and pseudo-elements (::before) add to the third.
  2. The universal selector (*) and combinators (space, >, +, ~) add nothing. :where() adds nothing at all. :is(), :not() and :has() count as their most specific argument. :nth-child(2n+1 of .x) counts as one pseudo-class plus its most specific selector.
  3. Scores compare from left to right: any ID beats any number of classes, and any class beats any number of types. Equal scores are settled by order in the stylesheet.
  • Specificity only decides between rules of the same origin and cascade layer. !important, inline styles, layers and order of appearance are separate steps of the cascade.

Calculated using SumPanda.com · https://sumpanda.com/css-specificity-calculator/

Results are estimates for general information. Verify important figures before relying on them.

Next step

How to use the css specificity calculator

  1. Paste selectors, one per line. A line with commas is treated as a list, and each selector in it is scored on its own.
  2. Read the table for the three numbers of each selector: IDs, then classes, attributes and pseudo-classes, then types and pseudo-elements.
  3. The row with the highest score is highlighted. If several tie, the one that appears last in the stylesheet wins.
  4. Fix any selector the page flags, such as an unclosed bracket or a combinator with nothing before it.

Formula

a = number of ID selectors (#id)

b = number of classes (.class), attributes ([x]) and pseudo-classes (:hover)

c = number of types (div) and pseudo-elements (::before)

:is(), :not(), :has() count as their most specific argument; :where() counts as nothing

Scores compare from left to right as three separate numbers, not as a single base 10 number. :nth-child(An+B of S) counts as one pseudo-class plus the most specific selector S.

Selectors and their scores

ul li scores 0,0,2 and li.red.level scores 0,2,1, so the class selector wins even though it is shorter in total. #x34y scores 1,0,0 and beats any number of classes. #s12:not(p) scores 1,0,1 because :not counts as its argument p.

:is(em, #foo) scores 1,0,0, since the most specific argument is the ID, while :where(em, #foo) scores 0,0,0. .foo :is(.bar, #baz) scores 1,1,0. In the starting list, a[href^="https"]:not(.ext, #skip) scores 1,1,1 and is the highest, because the type and the attribute count 0,1,1 and :not adds the ID from its list.

How the cascade uses specificity

When two rules set the same property on the same element, the browser first compares importance and origin, then cascade layers, and then specificity. Only after that does it use the order in the stylesheet. So a more specific selector wins over a later but less specific one, which is why adding a class sometimes does nothing and adding an ID suddenly does.

Inline styles and !important rules are outside the three numbers. Keeping specificity low and flat makes a stylesheet easier to override. Selectors with :where() are useful for defaults because they add nothing.

Reading the result

The score is about the selector alone and not about the page, so the page cannot tell you which element matches. To test whether a selector matches anything in a piece of HTML, use the CSS Selector Tester. The CSS Formatter tidies a stylesheet and the CSS and HTML Minifier shrinks it. For color work in the same stylesheet, see the Color Contrast Checker.

Assumptions and limits

  • Scores follow the Selectors Level 4 rules, including :is(), :not(), :has(), :where() and :nth-child() with an of-clause.
  • The legacy pseudo-elements :before, :after, :first-line and :first-letter count as pseudo-elements.
  • Up to 300 selectors are scored at a time. Comments and rule bodies in braces are ignored.
  • Scoring does not check that a selector is meaningful for the elements it targets, and nothing is sent anywhere.

Formulas reviewed October 10, 2026. See the calculation methodology for how SumPanda rounds, tests and sources its formulas.

Frequently asked questions

Is 0,1,10 higher or lower than 0,2,0?

Lower. The middle number is compared first, so 2 classes beat 1 class however many types follow. The three numbers are never combined into a single value.

Does the universal selector add specificity?

No. The asterisk, combinators such as the space or the greater-than sign, and the :where() pseudo-class all add nothing. A namespace prefix does not add either.

How does :not() count?

It counts as the most specific selector in its list, and the :not itself adds nothing. So :not(.a, #b) counts as the ID, 1,0,0, because the ID is more specific than the class.

Why is a pseudo-element counted with the types?

The rules put types and pseudo-elements in the same, lowest category, because they select by element rather than by a class, attribute or state.