How to use the CSS specificity calculator
Type or paste any CSS selector into the input field. The calculator instantly parses the selector and displays its specificity as a four-part score (inline, IDs, classes, elements). The breakdown panel on the right shows each category with a color-coded count so you can immediately see which part of the selector carries the most weight.
Use the quick example buttons to load common selector patterns and observe how specificity changes. Click "Add to History" to save the current result and compare it against other selectors. The history panel retains up to 20 entries so you can evaluate which rule wins in a cascade conflict. Click "Copy Result" to copy the selector and specificity string to your clipboard for documentation.
This tool is designed for debugging CSS cascade issues. When two rules target the same element and you cannot figure out why one wins, paste both selectors here and compare their scores. The one with the higher specificity (reading left to right) is the one the browser applies. If scores are identical, the rule that appears later in source order wins.
Understanding the specificity hierarchy
CSS specificity follows a strict hierarchy. Inline styles (the style attribute on an HTML element) have the highest specificity and override any stylesheet rule unless that rule uses !important. Below inline styles, ID selectors carry the next highest weight. A single ID selector (#header) outweighs any number of class selectors.
Class selectors (.btn), attribute selectors ([type="text"]), and pseudo-classes (:hover, :focus, :nth-child) all share the same specificity tier. Below that tier, element selectors (div, h1, p) and pseudo-elements (::before, ::after, ::first-line) form the lowest tier. The universal selector (*), combinators (>, +, ~), and the :where() pseudo-class contribute zero specificity.
When comparing two specificity values, the browser reads left to right. A specificity of 0,1,0,0 (one ID) always beats 0,0,99,99 (ninety-nine classes and ninety-nine elements). This is why deeply nested class-based selectors can still lose to a single ID selector—the ID tier simply outranks the class tier regardless of count.
Best practices for managing specificity
Modern CSS architecture recommends keeping specificity as low and flat as possible. Methodologies like BEM (Block Element Modifier) use single-class selectors for every component, producing consistent 0,0,1,0 specificity across the entire codebase. This makes the cascade predictable and eliminates specificity wars.
The CSS :where() pseudo-class is a powerful tool for library authors and design systems. Selectors inside :where() contribute zero specificity, meaning consumers can easily override library styles with a single class. For example, :where(.card .title) has specificity 0,0,0,0 while still selecting the correct elements.
Avoid using ID selectors in stylesheets. Reserve IDs for JavaScript hooks and fragment identifiers. If you need to override a third-party style that uses IDs, prefer using an attribute selector [id="sidebar"] which counts as a class-tier selector (0,0,1,0) instead of an ID-tier selector (0,1,0,0). This gives you the same targeting ability with lower specificity.
Specificity in CSS layers and cascade layers
CSS Cascade Layers (@layer) add another dimension to style resolution. Layers have their own priority order independent of specificity. A rule in a higher-priority layer overrides a rule in a lower-priority layer regardless of specificity. This means you can structure your CSS into layers (reset, base, components, utilities) and control override behavior without increasing specificity.
For example, utility classes in a utilities layer always override component styles in a components layer, even if the component selector has higher specificity. This pattern is increasingly adopted by CSS frameworks and design systems to create maintainable, conflict-free stylesheets.
Frequently Asked Questions
What is CSS specificity?
CSS specificity is the algorithm browsers use to determine which CSS rule applies when multiple rules target the same element. Specificity is calculated as a four-part score: inline styles, IDs, classes/attributes/pseudo-classes, and elements/pseudo-elements. Higher specificity wins. If two rules have equal specificity, the one that appears later in the stylesheet is applied.
How is specificity calculated?
Specificity is represented as four numbers (a,b,c,d). 'a' is 1 for inline styles, otherwise 0. 'b' counts the number of ID selectors (#id). 'c' counts class selectors (.class), attribute selectors ([attr]), and pseudo-classes (:hover, :focus). 'd' counts element selectors (div, p) and pseudo-elements (::before, ::after). Each level is compared left to right—a higher number in an earlier position always wins.
Does !important affect specificity?
No. !important is not part of the specificity calculation—it creates a separate layer of priority. An !important declaration always overrides normal declarations regardless of specificity. When two !important rules conflict, specificity determines which one wins among them. Using !important excessively makes CSS harder to maintain and debug.
What specificity does :not() have?
The :not() pseudo-class itself has zero specificity. However, the selector inside :not() does count. For example, :not(.active) adds one class-level specificity (0,0,1,0), and :not(#sidebar) adds one ID-level specificity (0,1,0,0). The :where() pseudo-class, by contrast, always has zero specificity regardless of its contents.
How do I override high-specificity selectors?
Instead of adding more IDs or using !important, consider restructuring your CSS. Use BEM naming conventions to keep selectors flat (one class per rule). Use CSS custom properties for values that need to change. Use the :where() function to wrap selectors you want to keep low-specificity. As a last resort, increase specificity by adding an extra class or attribute selector.
What is the specificity of a universal selector (*)?
The universal selector (*), combinators (+, >, ~, space), and the negation pseudo-class :not() itself all have zero specificity. They do not add to any of the four specificity categories. However, selectors inside :not() do count normally.
Privacy and methodology
This tool runs entirely in your browser. Selectors are parsed using regex-based pattern matching that counts ID, class, attribute, pseudo-class, element, and pseudo-element selectors according to the W3C specificity algorithm. No data is sent to any server. The calculator handles most common selector patterns including combinators, pseudo-classes, pseudo-elements, :not(), and attribute selectors.