CSS Specificity Calculator

Type a selector and see its specificity as three numbers, (a, b, c). Add a second selector to find out which rule wins when both set the same property.

Free Runs in your browser Checked Thursday, November 12, 2026

One selector, written as it would be in a stylesheet, such as #nav li.active > a:hover.

A selector to compare with the first. Leave it empty to read the specificity of one selector.

Result

Specificity (a, b, c) — a counts ID selectors, b counts classes, attributes and pseudo-classes, and c counts types and pseudo-elements.
Which rule wins — Shown when a second selector is given.
Parts counted

This tool runs in your browser. What you enter is not sent to us.

How to use it

  1. Type a selector into Selector, written as it is in your stylesheet.
  2. Type a second selector into Second selector (optional) to compare the two, or leave it empty.
  3. Read Specificity (a, b, c) for the first selector, and Which rule wins when you gave two.
  4. Use the Parts counted table to see which part of each selector gave each number.

How the three numbers are counted

The Selectors Level 3 Recommendation counts a selector in three columns. The tool compares the numbers from left to right: a first, then b, then c. The universal selector * and the combinators such as > and + are ignored.

  • a is the number of ID selectors, such as #nav.
  • b is the number of class selectors such as .active, attribute selectors such as [href], and pseudo-classes such as :hover.
  • c is the number of type selectors such as li or a, and of pseudo-elements such as ::before.

Pseudo-classes with arguments

:is(), :not() and :has() count as their most specific argument, so :is(#a, .b) is (1, 0, 0). :where() counts for nothing. :nth-child() counts as one pseudo-class plus the most specific selector in its "of S" list, so :nth-child(even of li, .item) is (0, 2, 0). These rules come from the Selectors Level 4 draft, which is an Editor's Draft and may change.

What the tool does not do

  • It counts a pseudo-element with arguments, such as ::part(x), as one pseudo-element, and does not read its argument.
  • It does not read nesting with &, and it takes one selector per box, not a list with commas.
  • It cannot see your stylesheet, so when two selectors tie it says that the later rule wins and leaves the order to you.

Worked example: a link in a navigation bar

The first selector, #nav li.active > a:hover, has one ID, #nav. It has two classes and pseudo-classes, .active and :hover, and two types, li and a. Its specificity is (1, 2, 2). The second selector, #nav a, has one ID and one type, so its specificity is (1, 0, 1). The first selector wins, because a is equal and b and c are higher.

Selector a b c
#nav li.active > a:hover 1 2 2
#nav a 1 0 1

Frequently asked questions

Why does an ID count in the first column?

The tool compares the columns from left to right, so the ID column a is decided first. A selector with one more ID has a higher a, and the classes and types in b and c are not looked at in that case.

Does the order of the rules matter?

Only when two selectors have the same specificity. The CSS Cascade Level 4 specification says the last declaration in document order wins at that point, so the later rule takes effect.

Why does :not(#a) add to the specificity?

The :not() pseudo-class itself is not counted, but its argument is. The Selectors Level 3 example #s12:not(FOO) is (1, 0, 1): one ID from #s12, and one type from the argument FOO.

Do the universal selector and the combinators add anything?

No. The universal selector is ignored, and so are the combinators such as >, + and ~. The example * in the Level 3 section has the specificity (0, 0, 0).

Does this tool include inline styles and !important?

No. It counts one selector. The cascade compares origin and importance before specificity, so a rule marked !important or an inline style can win whatever the selectors score. Compare only two selectors that set the same property with the same importance.

Is the selector I type sent anywhere?

No. The parsing runs in your browser, and nothing you type is stored or sent to our server. Check the result before you change a stylesheet.

Sources

Figures and text last checked on Thursday, November 12, 2026.

We use necessary cookies to run the site. With your consent, Google also uses advertising cookies to show personalised ads. If you reject them, you still see ads, but they are not personalised.