Enter any CSS selector to instantly calculate its specificity. The result is shown as three numbers (A, B, C): A = ID selectors, B = class selectors, attribute selectors, and pseudo-classes, C = type selectors and pseudo-elements.
Try these examples
Add multiple CSS selectors to compare their specificity side by side. The selector with the highest specificity wins when multiple rules target the same element.
Specificity Reference Table
| Selector Type | Example | Specificity |
|---|---|---|
| Inline style | style="..." | Highest priority |
| ID selector | #header | (1, 0, 0) |
| Class selector | .active | (0, 1, 0) |
| Attribute selector | [type="text"] | (0, 1, 0) |
| Pseudo-class | :hover | (0, 1, 0) |
| Type (element) selector | div | (0, 0, 1) |
| Pseudo-element | ::before | (0, 0, 1) |
| Universal selector | * | (0, 0, 0) |
| Combinators | > + ~ (space) | (0, 0, 0) |
:where() | :where(.x) | (0, 0, 0) |
CSS specificity determines which rule applies when multiple rules target the same element. It is calculated as three categories:
A – IDs: Each #id selector adds 1 to column A.
B – Classes: Each .class, [attribute], and :pseudo-class adds 1 to column B.
C – Elements: Each element name and ::pseudo-element adds 1 to column C.
Key rule: Column A always beats column B, and column B always beats column C, regardless of count. So
#id (1,0,0) beats .a.b.c.d.e.f.g.h.i.j (0,10,0).| Function | Specificity Rule | Example |
|---|---|---|
:not(S) | Takes the specificity of its most specific argument | :not(.hidden) p = (0,1,1) |
:is(S) | Takes the specificity of its most specific argument | :is(#hero, .banner) h1 = (1,0,1) |
:has(S) | Takes the specificity of its most specific argument | a:has(> img) = (0,0,2) |
:where(S) | Always zero specificity | :where(#main, .page) p = (0,0,1) |
When specificity is equal, CSS uses this order to determine which rule wins:
- Importance (
!importantdeclarations win over normal declarations) - Specificity (higher specificity wins)
- Source order (last rule defined wins when specificity is equal)
About !important: It does not change the specificity value. Instead, it creates a separate layer where all !important rules compete using their own specificity values.
- Thinking specificity is base-10: (0,1,0) always beats (0,0,99). Columns never overflow into each other.
- Forgetting :where() has zero specificity: Use
:where()to reset specificity in utility classes. - Confusing :not() specificity:
:not(.a)has the specificity of.a, not zero.:not()itself adds no specificity. - Old pseudo-element syntax:
:beforeand::beforehave the same specificity (0,0,1). Both count as pseudo-elements. - Using !important to fix specificity issues: Instead, increase the specificity of your selector or restructure your CSS.
| Selector | Breakdown | Specificity |
|---|---|---|
| * | universal | (0,0,0) |
| li | 1 element | (0,0,1) |
| ul li | 2 elements | (0,0,2) |
| ul li.active | 2 elements, 1 class | (0,1,2) |
| #nav .item | 1 ID, 1 class | (1,1,0) |
| div#sidebar *:link | 1 element, 1 ID, 1 pseudo-class | (1,1,1) |
| body #main .content h2:first-of-type | 2 elements, 1 ID, 1 class, 1 pseudo-class | (1,2,2) |
Difficulty:
0Score
0Answered
0Streak
0Best
Which selector has higher specificity?
VS