🎨 CSS Specificity Calculator

A CSS specificity calculator that breaks any selector into its (ID, class, element) score and compares two selectors to show which wins the cascade.

Free No Signup Required Browser-Based
#nav ul li.active a
(1, 1, 3)
1 ID · 1 class/attr/pseudo-class · 3 element/pseudo-element
nav a:hover
(0, 1, 2)
0 ID · 1 class/attr/pseudo-class · 2 element/pseudo-element

Selector A wins (higher specificity)

What CSS Specificity Calculator Does

CSS specificity exists to answer one question when two rules both apply to the same element and conflict: which one wins. The algorithm — count IDs, then classes/attributes/pseudo-classes, then elements/pseudo-elements, and compare in that order — is deceptively simple to state and easy to get wrong by eye once selectors get more than a couple of parts long, which is exactly the gap a calculator closes.

The trickiest real-world cases are the "forwarding" pseudo-classes — :not(), :is(), and :has() — which were specifically designed not to add their own specificity weight, but instead to inherit the specificity of whichever argument inside them is most specific. :where() is the deliberate exception: it always contributes zero, specifically so authors have a tool for writing broadly-matching selectors without specificity side effects.

How to Use CSS Specificity Calculator

  1. Paste a CSS selector to see its (ID, class, element) specificity score
  2. Add a second selector to compare which one would win
  3. Read the breakdown to see exactly what each part of the selector contributed

Formula Used by CSS Specificity Calculator

Specificity comparison

Specificity = (A, B, C), compared left to right

A
Count of ID selectors
B
Count of class selectors, attribute selectors, and pseudo-classes
C
Count of type (element) selectors and pseudo-elements

Worked example

#nav ul li.active a vs. nav a:hover

  1. #nav ul li.active a → 1 ID, 1 class, 3 elements → (1, 1, 3)
  2. nav a:hover → 0 IDs, 1 pseudo-class, 2 elements → (0, 1, 2)

Result: (1,1,3) beats (0,1,2) — the ID selector alone decides it, regardless of the element counts

How to Read Your Result

A single ID always beats any number of classes

Because comparison is lexicographic (A first, fully, before B is ever considered), a selector with one ID and nothing else — (1,0,0) — outranks a selector with fifty chained classes and no ID — (0,50,0). This is precisely what makes over-reliance on ID selectors for styling a maintenance headache: nothing short of another ID (or !important) can override it.

!important and inline styles operate outside this system entirely

They are not higher specificity values within the (A,B,C) system — they are separate override mechanisms in the CSS cascade that take precedence before specificity comparison is even reached, which is part of why overusing !important makes a stylesheet's behavior hard to reason about later.

Limitations & Accuracy Notes

  • This tool parses common selector syntax with a regex-based approach, not a full CSS selector grammar — deeply nested or unusual selector syntax may not parse perfectly.
  • Does not account for cascade layers (@layer) or the CSS @scope proximity rules, both of which can affect which rule ultimately applies independent of raw specificity.
  • Does not evaluate !important or inline style precedence, which override specificity comparison entirely.

Frequently Asked Questions

How is CSS specificity calculated?
As three counts, from highest to lowest priority: (A) the number of ID selectors, (B) the number of class selectors, attribute selectors, and pseudo-classes, and (C) the number of element (type) selectors and pseudo-elements. Selectors are compared by A first, then B, then C — a single ID selector (1,0,0) always beats any number of classes (0,n,0).
What about :not(), :is(), and :has()?
These "forwarding" pseudo-classes do not add to the count themselves — instead, they contribute the specificity of the most specific selector inside their parentheses. :where() is the exception: it always contributes zero specificity regardless of what is inside it, by design, specifically so it can be used to lower specificity intentionally.
Does inline style or !important show up here?
No — inline styles (style="...") outrank any selector specificity entirely, and !important overrides normal cascade order altogether. Both operate outside the (A,B,C) specificity system this tool calculates and are handled separately by the CSS cascade.
What happens when two selectors tie?
When A, B, and C are all equal, the selector that appears later in the stylesheet (or later in a tie-broken cascade layer/origin) wins — source order becomes the tiebreaker once specificity itself cannot decide.
Why is high specificity considered a code smell?
Overly specific selectors (deeply nested, ID-heavy) are hard to override later without matching or exceeding their specificity, which pushes future developers toward even more specific selectors or !important just to make a small style change — the specificity keeps escalating over a codebase's lifetime, which is why many CSS style guides recommend keeping selectors as flat and class-based as practical.
Does the order of parts within a single selector matter?
No — for a single compound selector like div.card#featured, the specificity count only depends on which selector types are present (1 element, 1 class, 1 ID here), not the order they're written in. Order only matters when comparing which of two different rules appears later in the source for tie-breaking.
Is my data stored?
No. Selectors are parsed entirely in your browser.
By OnlineToolHubs Team • September 2026