CSS Specificity Calculator
Calculate (a, b, c) specificity scores, compare selectors, and learn which rule wins.
How to Use the CSS Specificity Calculator
- Batch mode — paste one or more CSS selectors (one per line) to calculate and rank all of them at once.
- Compare mode — enter two selectors side by side to see which one wins and why.
- Quiz mode — test your knowledge by guessing which of two selectors has higher specificity.
- Read the bars — red bars show ID count, green bars show class/attribute/pseudo-class count, blue bars show element/pseudo-element count.
How CSS Specificity Works
Specificity is the algorithm CSS uses to determine which rule applies when multiple declarations target the same element and property. It is calculated as a three-number score (a, b, c) — sometimes written (0, 0, 0) or as three digits separated by commas. A higher leftmost number always wins, regardless of how large the rightmost numbers are.
The three columns represent: (a) inline styles — applied via the style attribute, always the most specific; (b) ID selectors — selectors using #id; (c) class, attribute, and pseudo-class selectors — .class, [attr], :hover; and within column c there is an additional sub-count for element selectors and pseudo-elements (div, ::before).
Specificity Scoring Table
- Inline style (style="…") — (1, 0, 0, 0)
- ID selector (#id) — (0, 1, 0, 0)
- Class selector (.class) — (0, 0, 1, 0)
- Attribute selector ([href], [type="text"]) — (0, 0, 1, 0)
- Pseudo-class (:hover, :first-child, :not(x)) — (0, 0, 1, 0)
- Element selector (div, p, a) — (0, 0, 0, 1)
- Pseudo-element (::before, ::after, ::first-line) — (0, 0, 0, 1)
- Universal selector (*) — (0, 0, 0, 0)
- Combinators (+, >, ~, space) — (0, 0, 0, 0)
Special Cases
Several modern CSS selectors have non-obvious specificity behaviors. :not() has no specificity of its own, but its argument contributes. :is() takes the highest specificity of all selectors inside it — so :is(#id, .class) has the specificity of #id. :where() always contributes zero specificity, making it useful for low-specificity utility selectors that are easy to override. CSS layers (@layer) interact with specificity in a layered cascade that is separate from selector specificity.
Common Specificity Mistakes
- Using
#idin component CSS makes it nearly impossible to override without another ID or!important - Deeply nesting selectors (
.page .content .section .title) creates unnecessarily high specificity - Overusing
!importantto "fix" specificity issues creates a maintenance nightmare - Assuming more element selectors will beat a class — they never will (1000 elements = score of 1000 in column c, but one class also scores 1 in column b which is higher)
Best Practices for Managing Specificity
Modern CSS methodologies like BEM (Block Element Modifier), ITCSS, and utility-first frameworks like Tailwind are largely designed to control specificity. BEM keeps all component styles at a single-class specificity (0, 0, 1, 0), making them easy to override. ITCSS layers styles from least specific (elements) to most specific (utilities, overrides). CSS custom properties (variables) are resolved before the cascade, so they are useful for theming without specificity conflicts. For deeper learning, also explore the CSS Unit Converter and Easing Editor.