Skip to content

CSS Specificity Calculator

Paste any CSS selector and get its specificity score broken into the three components the cascade uses: ID count, class/attribute/pseudo-class count, and element/pseudo-element count. The result tells you exactly why one rule wins over another when both target the same element.

Why Specificity Wins Cascade Fights

CSS resolves conflicts between competing rules using specificity before it falls back to source order. A selector's specificity is a three-number tuple — commonly written (a,b,c) or 0-0-0. a counts ID selectors, b counts classes, attributes, and pseudo-classes, and c counts element and pseudo-element selectors. Higher beats lower, comparing left to right. (0,1,0) (one class) beats (0,0,9) (nine elements) every time, because the class column outranks the element column regardless of how many elements stack up.

Inline styles add a fourth column above all three. !important sidesteps the whole calculation and creates its own priority lane, with !important inline styles beating !important author rules beating !important user rules. The cascade gets predictable once you can name each rule's score.

How the Calculator Works

The selector gets parsed into atoms. Each #id adds 1 to column a. Each .class, [attr], or :pseudo-class adds 1 to column b. Each tag name or ::pseudo-element adds 1 to column c. The universal selector * and combinators (>, +, ~) contribute zero. Two CSS Level 4 wrinkles get special handling: :where() always contributes zero, no matter what's inside it, and :is() and :not() take the specificity of their most-specific argument.

Cascade Layers (@layer) sit above specificity entirely — a layered rule loses to any unlayered rule regardless of selector score, which is why you can ship reset CSS in a layer and have author rules win effortlessly.

When Specificity Bites

Most specificity bugs come from one of three patterns: a long selector chain like div.container ul.nav li.item a that's hard to override without copying the chain; an !important declaration in a vendor stylesheet that forces a second !important just to match it; and an inline style= attribute set by JavaScript that wins against any author rule that isn't !important. Knowing the score makes the fix obvious: lower the original specificity, use a layer, or, as a last resort, match the !important. Use the CSS button generator or the CSS animation generator to produce overridable single-class rules.

How We Compare

Specifishity by Estelle Weyl is the canonical reference graphic and worth bookmarking. The Polypane and Browserstack online calculators do roughly what this tool does. Compared to those, this calculator handles the CSS Level 4 selector quirks (:where() contributing zero, :is() taking the max of its arguments) correctly, runs entirely in the browser, and links into the rest of the UDT CSS toolset so a tricky selector flows into a clean rewrite.

Frequently Asked Questions

What is CSS specificity?+
Specificity is the algorithm browsers use to decide which CSS rule applies when multiple rules target the same element. It's calculated as a tuple (a, b, c) where a = ID selectors, b = class/attribute/pseudo-class selectors, c = element/pseudo-element selectors. Higher specificity wins.
How does !important affect specificity?+
!important overrides all specificity calculations. It's not part of the specificity score itself — it creates a separate 'layer' that always wins over non-important rules. When multiple !important rules conflict, normal specificity applies among them.
Does :where() contribute to specificity?+
No. :where() always has zero specificity, regardless of its arguments. This makes it useful for writing easily-overridable defaults. In contrast, :is() takes the specificity of its most specific argument.
Why does my CSS rule not apply?+
The most common reason is that another rule with higher specificity is overriding it. Use this calculator to compare selector specificity. Other factors include source order (later rules win at equal specificity) and inheritance.
What specificity does inline style have?+
Inline styles (style attribute) have a specificity of (1,0,0,0) — they override any selector-based rule. Only !important declarations can override inline styles.
How is :not() specificity calculated?+
:not() takes the specificity of its argument. For example, :not(.active) adds one class-level specificity (0,1,0). The :not() pseudo-class itself contributes nothing.
What's the specificity of the universal selector (*)?+
Zero. The universal selector (*), combinators (+, >, ~), and the negation pseudo-class container itself contribute nothing to specificity.
What happens when two selectors have equal specificity?+
When specificity is equal, the rule that appears later in the CSS wins (source order). This is why the cascade matters — the order of your stylesheets and rules affects the outcome.
How do CSS layers (@layer) affect specificity?+
CSS Cascade Layers (@layer) create a new priority system above specificity. Rules in a later layer override earlier layers regardless of specificity. Within the same layer, normal specificity rules apply.

📖 Learn More

Related Article CSS Specificity Explained: The Complete Guide →

Built by Derek Giordano · Part of Ultimate Design Tools

Privacy Policy · Terms of Service