# CSS specificity calculator

> Paste one or more CSS selectors, or a whole stylesheet, and read each selector's specificity as the (A, B, C) triple of Selectors Level 4, every simple selector named with the column it adds to, the selectors ranked the way the cascade ranks them with ties called out, and the special cases spelled out: :where() counts for nothing, :is(), :not() and :has() take their most specific argument, :nth-child(of) adds its argument, the universal selector adds nothing, a repeated class counts twice, a legacy single-colon pseudo-element counts as one. With the reminder of the five things the cascade checks before specificity.

- Tool: https://ronutz.com/en/tools/css-specificity-calculator
- Family: Web & HTTP

---

## What it does

Reads one or more CSS selectors (one per line, comma-separated, or a whole stylesheet pasted in, whose declaration blocks and at-rule preludes are dropped) and computes each selector's specificity as the (A, B, C) triple of Selectors Level 4, with every simple selector named and the column it adds to. The selectors are ranked the way the cascade ranks them, ties are called out (order of appearance decides there), and each special rule the selector relied on is explained beside it.

## The counting

From Selectors Level 4, "Calculating a selector's specificity":

- **A** counts ID selectors (`#main`).
- **B** counts class selectors (`.nav`), attribute selectors (`[type="text"]`) and pseudo-classes (`:hover`).
- **C** counts type selectors (`li`) and pseudo-elements (`::before`).
- The universal selector (`*`) is ignored; combinators add nothing.
- Specificities are compared column by column: a larger A wins; if A ties, a larger B; if B ties, a larger C; if all tie, the specificities are equal.
- "Repeated occurrences of the same simple selector are allowed and do increase specificity": `.a.a` is (0,2,0).

The special cases the specification spells out, and the calculator applies:

- `:is()`, `:not()` and `:has()`: the specificity "is replaced by the specificity of the most specific complex selector in its selector list argument". `:not(em, strong#foo)` is (1,0,1).
- `:nth-child()` and `:nth-last-child()` with an `of` clause: one pseudo-class "plus the specificity of the most specific complex selector in its selector list argument". `:nth-child(even of li, .item)` is (0,2,0).
- `:where()`: "replaced by zero". `.qux:where(em, #foo#bar#baz)` is (0,1,0).
- The legacy single-colon pseudo-elements of CSS2 (`:before`, `:after`, `:first-line`, `:first-letter`) are pseudo-elements and count in C.
- From the CSS Shadow Module Level 1: `:host` is a pseudo-class; `:host()` and `:host-context()` are a pseudo-class plus their argument; `::slotted()` is a pseudo-element plus its argument. `::part()` is counted as one pseudo-element (the module defers its exact rule to CSS Pseudo-Elements Level 4; the assumption is stated on the page).

The calculator reproduces the specification's examples table: `*` (0,0,0), `LI` (0,0,1), `UL LI` (0,0,2), `UL OL+LI` (0,0,3), `H1 + *[REL=up]` (0,1,1), `UL OL LI.red` (0,1,3), `LI.red.level` (0,2,1), `#x34y` (1,0,0), `#s12:not(FOO)` (1,0,1), `.foo :is(.bar, #baz)` (1,1,0).

## Before specificity

Specificity decides only when everything above it in the cascade is equal. CSS Cascading and Inheritance Level 5 sorts declarations by, in descending order of priority: origin and importance (an `!important` author declaration beats every normal one, whatever the selector), context (shadow trees), element-attached styles (a `style` attribute beats any rule of the same importance), cascade layers (the last layer wins for normal declarations, the first for important ones), then specificity, then order of appearance (the last declaration in document order wins, with style attributes placed after every style sheet). The page lists these so a surprising winner can be traced to the right step.

## Limits

- The calculator reads syntax, not a document. It cannot know whether a selector matches anything, and for a selector list the specificity in effect in a real match is that of the most specific member that matches; the page ranks the members individually.
- Namespace prefixes (`ns|p`) are read but not resolved.
- Unknown pseudo-classes and pseudo-elements are counted by their shape (one colon B, two colons C), which is what the grammar says; whether a browser supports them is another question.
- Implementations may clamp very large counts; the calculator does not.

## Sources

- [Selectors Level 4, W3C Working Draft 22 January 2026: Calculating a selector's specificity](https://www.w3.org/TR/selectors-4/#specificity-rules) (read 2026-10-05)
- [CSS Cascading and Inheritance Level 5, W3C Candidate Recommendation Snapshot 13 January 2022: Cascade Sorting Order](https://www.w3.org/TR/css-cascade-5/#cascade-sort) (read 2026-10-05)
- [CSS Shadow Module Level 1, Editor's Draft 28 April 2026](https://drafts.csswg.org/css-shadow-1/) (read 2026-10-05)

## Standards and references

- [Selectors Level 4, W3C Working Draft 22 January 2026: Calculating a selector's specificity](https://www.w3.org/TR/selectors-4/#specificity-rules) - A counts ID selectors, B class, attribute and pseudo-class selectors, C type selectors and pseudo-elements, the universal selector ignored; :is(), :not() and :has() take the most specific argument; :nth-child() and :nth-last-child() count as one pseudo-class plus their argument; :where() is zero; comparison column by column; repeated occurrences increase specificity; the examples table
- [CSS Cascading and Inheritance Level 5, W3C Candidate Recommendation Snapshot 13 January 2022: 6.1 Cascade Sorting Order](https://www.w3.org/TR/css-cascade-5/#cascade-sort) - origin and importance, context, element-attached styles, cascade layers, specificity, order of appearance, in descending order of priority; each declaration has the specificity of its style rule
- [CSS Shadow Module Level 1, Editor's Draft 28 April 2026: the specificity of :host, :host(), :host-context() and ::slotted()](https://drafts.csswg.org/css-shadow-1/) - :host is a pseudo-class; :host() and :host-context() are a pseudo-class plus the argument; ::slotted() is a pseudo-element plus the argument; ::part() deferred to CSS Pseudo-Elements Level 4

## Related reading

- [How a selector finds its elements: Selectors Level 4 read as a matching algorithm](https://ronutz.com/en/learn/how-a-selector-finds-its-elements.md): A CSS selector is a question asked of a tree, and the specification says exactly how the question is answered: compound by compound, right to left, with the document language deciding what counts as the same name. Where case matters and where it does not, the seven attribute operators and the empty string that matches nothing, how siblings are counted, what :is(), :not(), :where() and :has() do to validity and specificity, which pseudo-classes a static document can never answer, and what browsers do with a selector that ends inside a bracket.
- [How the HTML parser repairs your markup, and why the repairs are the same in every browser](https://ronutz.com/en/learn/how-the-html-parser-repairs-your-markup.md): A browser never rejects HTML. Whatever you paste, a tree comes out, and the HTML Standard says exactly which tree: the elements the parser creates for you, the end tags it supplies, the formatting elements it splits, the content it lifts out of tables, the comments it makes of your typos, and the quirks mode it falls into without a DOCTYPE. The 52 named parse errors, the five repairs worth knowing by name, what view source and inspect element disagree about, and why WCAG 2.2 could drop its parsing criterion without lowering the bar.
- [Specificity, counted by the specification, and the five things the cascade checks first](https://ronutz.com/en/learn/css-specificity-and-the-cascade.md): Every stylesheet war ends in the same place: two rules want the same property on the same element and one of them wins. CSS decides with a short, exact procedure, and specificity is only its fifth step. Here is how Selectors Level 4 counts a selector into three numbers, what :is(), :where(), :not() and :nth-child(of) do to the count, the ten examples the specification itself gives, and the five criteria the cascade settles before it ever looks at specificity.
