Why it matters
When a style refuses to apply, the cause is usually specificity: another rule with a stronger selector wins. Reaching for !important fixes it today and makes the next change harder.
Specificity has three parts (IDs, then classes, attributes and pseudo-classes, then elements and pseudo-elements), and newer pseudo-classes change the rules: :where() adds nothing, while :is() and :not() take their strongest argument. This calculator follows the Selectors Level 4 rules exactly.
How it works
- InputSelectors, or a whole stylesheet
- In your browserScored with the Selectors Level 4 rules
- OutputA ranked list, with ties and ID-heavy selectors flagged
Where it fits in a designer's workflow
- Plan
- Design
- Build
- Test
- Launch
By the numbers
Show the numbers as a table
| Selector | IDs | Classes | Elements |
|---|---|---|---|
| p | 0 | 0 | 1 |
| .card p | 0 | 1 | 1 |
| nav a:hover | 0 | 1 | 2 |
| ul li::before | 0 | 0 | 3 |
| :where(#main) .btn | 0 | 1 | 0 |
| .btn.btn-primary | 0 | 2 | 0 |
| #main .btn | 1 | 1 | 0 |
| :is(#a, .b) p | 1 | 0 | 1 |
How to use it
- Paste one selector per line, or a whole stylesheet.
- Read the table: the top row wins when both rules match the same element.
- Rows with the same score are ties: the later rule in the CSS wins.
- Download the report to share with your team.
FAQ
How is specificity written?
As three numbers, IDs, classes and types, such as (1, 2, 1). Compare from the left: one ID beats any number of classes.
Does inline style or !important count?
They sit outside specificity. An inline style beats any selector, and !important beats both, which is why it's best avoided.
Why does :where() count as zero?
It was designed for low-priority defaults that are easy to override, such as a CSS reset.
What about @layer?
Cascade layers are checked before specificity: a rule in a later layer wins even with a weaker selector. This tool compares selectors within the same layer.