🎯 CSS Specificity Calculator
Calculate and compare CSS selector specificity scores - (A, B, C) breakdown
📊 Key Data Points
(0,1,0,0)
ID selector specificity — beats any number of class selectors
:where() = 0
:where() has zero specificity — the safest way to apply default styles
Source order
Last rule wins when specificity is equal — source order only matters for ties
CSS Specificity Calculator -- Complete USA Guide 2026
CSS specificity determines which rule wins when multiple selectors target the same element. The specificity scoring system — IDs (0,1,0,0), classes/attributes/pseudo-classes (0,0,1,0), elements/pseudo-elements (0,0,0,1) — is not obvious, and unexpected specificity issues cause hours of debugging.
This calculator scores any CSS selector and ranks multiple selectors against each other. Runs in your browser.
**Long-tail searches answered here:** calculate css selector specificity online free, css specificity score calculator with explanation, which css selector wins specificity checker browser.
For other CSS debugging tools, pair with CSS Unit Converter.
🔬 How This Calculator Works
Specificity is a 4-part score: (inline styles, IDs, classes/attributes/pseudo-classes, elements). The calculator parses each selector component and assigns the correct score: #id to (0,1,0,0), .class, [attr], :hover to (0,0,1,0), div, p, ::before to (0,0,0,1). The :not(), :is(), and :has() pseudo-classes carry the specificity of their argument. :where() has zero specificity.
✅ What You Can Calculate
Visual 4-part score breakdown
Shows the (0,0,0,0) score broken down by component — helps understand why .parent .child (0,0,2,0) beats .single-class (0,0,1,0).
Multiple selector ranking
Enter multiple selectors and see them ranked by specificity. Essential for debugging why is my style not applying.
:is() and :not() specificity
Modern pseudo-classes like :is(), :not(), :has(), and :where() have non-obvious specificity rules. :where() has zero specificity; :is() and :has() take the highest specificity of their argument.
Specificity war prevention
Calculating before writing helps avoid specificity escalation — adding more IDs to override another rule which adds more IDs in response.
🎯 Real Scenarios & Use Cases
Debugging style overrides
Your hover style is not applying. Enter your hover selector and the selector you are trying to override here. The higher specificity score wins.
CSS architecture reviews
Paste component selectors from your stylesheet to verify no unintended high-specificity rules are present. High specificity in component CSS creates hard-to-override styles.
Learning CSS specificity
Manually score a few selectors here to internalize the rule. After calculating .nav .link:hover (0,0,2,1) vs #main a:hover (0,1,1,1), the ID weight becomes concrete.
Migrating from BEM to utility-first
Verify that utility classes will not be overridden by legacy BEM selectors with unexpectedly high specificity.
💡 Pro Tips for Accurate Results
Avoid ID selectors in CSS. One ID beats 255 class selectors. Stick to class selectors (0,0,1,0) in component CSS to keep styles overridable.
Use :where() for zero-specificity defaults. :where(h1,h2,h3) { margin-top: 1em } — any class selector can override with no specificity escalation.
!important only escalates conflicts. The next override also needs !important. Use :where() or lower-specificity selectors instead.
Inline styles beat everything. style=color:red has specificity (1,0,0,0) — higher than any stylesheet selector. Avoid inline styles in component markup.
🔗 Use These Together
🏁 Bottom Line
CSS specificity bugs are among the hardest to debug. This calculator makes the winning rule explicit before you write a new selector. For CSS debugging: CSS Unit Converter and Responsive Breakpoints.
#nav .menu-item a:hoverbutton.btn.primaryh1 + pdiv > .container[data-active="true"]Specificity Reference
(1,0,0)Inline styles
style="..."
(0,1,0)ID selector
#main
(0,0,1)Class selector
.active
(0,0,1)Attribute selector
[type="text"]
(0,0,1)Pseudo-class
:hover :focus
(0,0,1)Element
div h1 p
(0,0,1)Pseudo-element
::before
(0,0,0)Universal
*
How is CSS specificity calculated?
Specificity is three numbers (a, b, c) compared left to right. (a) counts ID selectors (#id). (b) counts class selectors (.class), attribute selectors ([type='text']), and pseudo-classes (:hover, :first-child). (c) counts element selectors (div, p, span) and pseudo-elements (::before, ::after). The universal selector (*), combinators (+, >, ~), and :is() with a universal argument add nothing. Compare left to right: a higher (a) always beats a lower (a) regardless of (b) and (c) values. Example: #nav (1,0,0) beats .nav ul li.active (0,2,2) which beats div p span (0,0,3).
Why does !important override specificity?
!important steps outside the normal specificity system. A declaration with !important beats all non-important declarations regardless of specificity. When two !important rules conflict, specificity breaks the tie. The intent: user accessibility stylesheets (users who need large text can override site styles), not for fixing specificity battles in application CSS. In application code, !important almost always signals a specificity problem that should be fixed at the selector level. Adding !important creates specificity debt — the next developer needs to also use !important and higher specificity to override it.
How does inline style specificity compare to selector specificity?
Inline styles (style='color: red' directly on the HTML element) have specificity (1,0,0,0) — a fourth column that beats all CSS selector specificity. An inline style overrides any selector, including #id selectors, without !important. This is why overriding third-party widget styles with inline attributes is sometimes used as a last resort. CSS Custom Properties defined inline propagate through the cascade normally, but the variable definition itself has inline specificity.
Does CSS nesting affect specificity?
CSS nesting follows the same specificity rules as if the nested selector were written flat. .parent .child has specificity (0,2,0) — same as writing it explicitly. The :is() pseudo-class uses the specificity of its most specific argument: :is(#id, .class) has specificity (1,0,0) because #id is most specific. :where(), on the other hand, always contributes zero specificity — extremely useful for utility and reset CSS that should be easily overridable.
What is the best way to avoid specificity wars in a codebase?
Several approaches: BEM (Block Element Modifier) methodology uses only single-class selectors like .nav__item--active, keeping all specificity at (0,1,0). CSS Modules and CSS-in-JS solutions generate unique class names per component, making selector conflicts structurally impossible. Tailwind uses utility classes at (0,1,0) specificity. For traditional CSS: never use ID selectors in CSS, never nest more than two levels deep, and use :where() for any base/reset styles that must be easily overridable.
How do :not(), :is(), and :has() specificity work?
:not() itself contributes zero specificity, but its argument does. :not(.active) has specificity (0,1,0). :not(#id) has specificity (1,0,0). :is() uses the specificity of its most specific argument — :is(h1, .title, #heading) has specificity (1,0,0) even though two arguments are lower. :where() always contributes zero specificity regardless of arguments — its key advantage for utility CSS. :has() uses the specificity of its most complex argument, like :is().
What other CSS debugging tools are on this site?
The Color Contrast Checker verifies accessibility compliance after identifying which color rule is applying. The Flexbox Generator and Grid Generator build layout rules correctly, reducing the need to override positioning with high-specificity selectors. The CSS Animation Generator creates keyframe animations without needing to override existing transitions. The Box Shadow Generator produces clean single-class declarations. All are in the Dev Tools CSS section.