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.
Web & HTTP10 selectors. The most specific is .foo :is(.bar, #baz) at 1,1,0.
Each selector's specificity
| rank | selector | A | B | C | A,B,C |
|---|---|---|---|---|---|
| 10 | * | 0 | 0 | 0 | 0,0,0 |
| 9 | LI | 0 | 0 | 1 | 0,0,1 |
| 8 | UL LI | 0 | 0 | 2 | 0,0,2 |
| 7 | UL OL+LI | 0 | 0 | 3 | 0,0,3 |
| 6 | H1 + *[REL=up] | 0 | 1 | 1 | 0,1,1 |
| 5 | UL OL LI.red | 0 | 1 | 3 | 0,1,3 |
| 4 | LI.red.level | 0 | 2 | 1 | 0,2,1 |
| 3 | #x34y | 1 | 0 | 0 | 1,0,0 |
| 2 | #s12:not(FOO) | 1 | 0 | 1 | 1,0,1 |
| 1 | .foo :is(.bar, #baz) | 1 | 1 | 0 | 1,1,0 |
A counts ID selectors; B counts class selectors, attribute selectors and pseudo-classes; C counts type selectors and pseudo-elements. The universal selector counts for nothing. Specificities compare column by column, A first (Selectors Level 4).
Piece by piece
- 1
*0,0,0* 0*: the universal selector is ignored when counting (Selectors Level 4).
- 2
LI0,0,1LI C - 3
UL LI0,0,2UL C(descendant)LI C - 4
UL OL+LI0,0,3UL C(descendant)OL C+LI C - 5
H1 + *[REL=up]0,1,1H1 C+* 0[REL=up] B*: the universal selector is ignored when counting (Selectors Level 4).
- 6
UL OL LI.red0,1,3UL C(descendant)OL C(descendant)LI C.red B - 7
LI.red.level0,2,1LI C.red B.level B - 8
#x34y1,0,0#x34y A - 9
#s12:not(FOO)1,0,1#s12 A:not(FOO) C:not(FOO): the specificity of :not() is that of the most specific selector in its argument list; the negation changes nothing.
- 10
.foo :is(.bar, #baz)1,1,0.foo B(descendant):is(.bar, #baz) A:is(.bar, #baz): the specificity of :is() is that of the most specific selector in its argument list.
What the cascade checks before specificity
Specificity decides only when everything above it is equal. CSS Cascading and Inheritance Level 5 sorts declarations by these criteria, in descending order of priority:
- Origin and importance: transitions first, then important user-agent, important user, important author, animations, normal author, normal user, normal user-agent declarations. An !important author declaration beats every normal one regardless of selector.
- Context: between shadow-tree contexts, the outer context wins for normal declarations and the inner one for important declarations.
- Element-attached styles: a style attribute beats any style rule of the same importance.
- Cascade layers: for normal declarations the last layer wins, for important ones the first; declarations outside any layer sit in an implicit final layer.
- Specificity: the triple compared here. Each declaration has the specificity of its rule's selector.
- Order of appearance: the last declaration in document order wins, with style attributes placed after every style sheet.
The calculator reads selector syntax, not a document: it cannot know whether a selector matches anything, and a selector list is ranked by its own members, while in a real match the specificity in effect is that of the most specific member that matches. Namespaces are read but not resolved. The counting follows Selectors Level 4 (Working Draft, 22 January 2026) and the cascade order follows CSS Cascade Level 5; both are cited under Sources.
Referanser
- Selectors Level 4, W3C Working Draft 22 January 2026: Calculating a selector's specificity
- CSS Cascading and Inheritance Level 5, W3C Candidate Recommendation Snapshot 13 January 2022: 6.1 Cascade Sorting Order
- CSS Shadow Module Level 1, Editor's Draft 28 April 2026: the specificity of :host, :host(), :host-context() and ::slotted()