๐Ÿค–NEW:AI-Powered Incremental Builds โ€” your site updates in under 30 seconds. See what's new โ†’
Developer Utility ยท 100% Client-Side

CSS Specificity Calculator

Paste one or more CSS selectors to see the (A, B, C) specificity score with a breakdown of every component. Debug cascade conflicts instantly.

Try an example

Specificity Results

Results appear here as you typeโ€ฆ

Specificity Reference

Selector typeExampleScore
Inline stylestyle="..."1,0,0,0
ID selector#hero0,1,0,0
Class selector.card0,0,1,0
Attribute selector[href]0,0,1,0
Pseudo-class:hover0,0,1,0
Element typediv0,0,0,1
Pseudo-element::before0,0,0,1
Universal selector*0,0,0,0
:where() pseudo-class:where(.x)0,0,0,0

Mastering the CSS Cascade and Specificity

1. The full cascade: origin, specificity, and order

Specificity is only one layer of the full CSS cascade algorithm. Before specificity is even considered, the browser sorts declarations by origin and importance (user-agent styles, then author styles, then author !important, then user !important, roughly in that priority), and since CSS Cascade Layers arrived, by @layer order within the same origin. Only when two competing declarations land in the same origin/importance/layer tier does specificity become the tiebreaker โ€” and only when specificity is also exactly equal does source order (last rule wins) make the final call.

2. How to read an (A, B, C) score correctly

The three numbers are compared as separate tiers, not combined into a single decimal or summed value โ€” this trips up nearly everyone learning specificity for the first time. A selector with one ID (1, 0, 0) always beats a selector with fifty classes (0, 50, 0), because A is compared first and 1 > 0 settles it immediately; B and C are never even examined in that comparison. Only when A is tied does B become the deciding factor, and only when both A and B are tied does C matter.

3. Common specificity fights in real WordPress themes

Page builders (Elementor, Divi, WPBakery) frequently generate deeply nested, highly specific selectors auto-attached to elements, which is exactly why custom CSS added through the Customizer or a child theme so often "doesn't work" โ€” it's not broken, it's simply losing a specificity fight against builder-generated rules. The fix is rarely to reach for !important; instead, match or slightly exceed the builder's selector depth, or use a CSS Cascade Layer to declare your custom styles as a strictly higher-priority layer regardless of selector depth.

4. Modern CSS tools for avoiding specificity wars

Two relatively recent CSS features exist specifically to reduce specificity conflicts: the :where() pseudo-class lets you write default/reset styles with guaranteed zero specificity so they're always trivially overridable, and @layer (CSS Cascade Layers) lets you explicitly order groups of rules by declared priority โ€” a rule in a later-declared layer always beats a rule in an earlier layer, regardless of each rule's own specificity. Together these let teams write far more predictable CSS architecture without resorting to specificity-inflation tricks like selector chaining or !important.

5. A practical debugging workflow

When a style "isn't applying," open browser DevTools, select the element, and look at the Styles panel โ€” it already shows every matching rule with strikethrough on any that are being overridden, which is usually the fastest path to an answer. Use this calculator when you need to understand precisely why one selector beats another, or when planning new CSS and want to keep specificity intentionally low and predictable before you write it, rather than debugging a conflict after the fact.

Frequently Asked Questions

What is CSS specificity?

CSS specificity is a weight system that determines which CSS rule wins when multiple rules target the same element. This tool calculates it as three numbers (A, B, C) matching the columns shown in your results above: A = ID selectors (#hero), B = classes (.card), attribute selectors ([href]), and pseudo-classes (:hover), and C = element type selectors (div, p) and pseudo-elements (::before). Inline styles (style="...") always outrank every selector-based rule regardless of A/B/C and are not part of this selector-only calculation. Higher specificity wins when two rules target the same element.

How is specificity calculated?

Count each component: IDs contribute to A, classes/attributes/pseudo-classes contribute to B, and element types/pseudo-elements contribute to C. Compare left-to-right โ€” a higher A always wins regardless of B or C, a higher B always wins regardless of C (this is NOT decimal math; 0,1,0 beats 0,0,99). Two rules at exactly equal specificity resolve by source order โ€” the rule that appears later in the stylesheet wins.

Does !important override specificity?

Yes. !important overrides the normal specificity cascade entirely. When two declarations both use !important, specificity applies again to break the tie between them. The selector with the higher specificity wins. Overuse of !important is a common source of CSS maintenance problems precisely because it short-circuits the predictable cascade.

How can I lower specificity to avoid overrides?

Use lower-specificity selectors (classes instead of IDs), the :where() pseudo-class (which always contributes 0 specificity regardless of what's inside its parentheses, unlike :is() and :not() which count their argument's specificity), or CSS Cascade Layers (@layer) to establish explicit priority ordering between groups of rules without relying on specificity fights at all.

Why do :is() and :not() count differently from :where()?

Per the CSS Selectors Level 4 spec, :is() and :not() take on the specificity of their single most specific argument โ€” so :not(.foo) contributes a class (B), and :not(#foo) contributes an ID (A). The :where() pseudo-class is the one deliberate exception: it always contributes zero specificity no matter how specific its argument is, which makes it useful for writing low-priority default styles (like in a CSS reset or design-system base layer) that are trivially easy for any other selector to override.

Does the order of classes or IDs in a selector matter for specificity?

No. Specificity is purely a count of how many IDs, classes/attributes/pseudo-classes, and elements/pseudo-elements appear in the selector โ€” .a.b.c has the same specificity as .c.b.a. What DOES matter is the combinator structure (descendant, child, sibling) only insofar as it changes which elements match, not the specificity score itself. Source order in the stylesheet only comes into play as a tiebreaker when two different selectors compute to the exact same specificity.

Why is my selector matching, but a different style is being applied?

This is almost always a specificity conflict โ€” a different rule targeting the same element has equal or higher specificity and either comes later in the stylesheet (same specificity, source-order tiebreak) or genuinely outranks yours. Paste both competing selectors into this tool to compare their (A,B,C) scores directly; if they're equal, check which rule is declared later in your CSS files (including how your build tool or theme orders stylesheet imports).