CSS Specificity Calculator – Calculate Selector Specificity Free Online

Use the free CSS Specificity Calculator below: your data never leaves your browser — all work happens on your device, and nothing is uploaded to any server.

Why Specificity Decides Your Styles

Every CSS developer has met the same mystery: a rule that should apply does not, and the browser seems to ignore it. The usual cause is specificity, the scoring system browsers use when several rules target the same element and property. The rule with the highest score wins, regardless of order, and only when scores tie does the later rule win. Understanding that scoring system turns hours of trial and error into a quick calculation.

Specificity is written as three numbers: IDs, classes, and elements. An ID selector like #main scores (1, 0, 0). A class like .card scores (0, 1, 0). An element like div scores (0, 0, 1). Compare the numbers left to right, like a three-digit number: (1, 0, 0) beats (0, 99, 99), because the ID column outweighs everything in the later columns. That left-to-right rule is the whole game.

How to Use the Tool

Type a selector into the first box and its score appears immediately, with the breakdown of IDs, classes, and elements. Type a second selector to compare: the tool tells you which one wins, or that they tie, in which case the later rule in the stylesheet decides. Use it when a style is not applying, when you are choosing between two selectors, or when you are reviewing someone else’s CSS and wondering why a rule lost.

Try it on your own stylesheets. Paste in the selector that is losing and the one that is winning, and the comparison usually explains the mystery at once. The common surprise is a long chain of classes losing to a single ID, or a rule with many elements losing to one class, because the columns do not mix the way intuition suggests.

What Counts in Each Column

The ID column counts ID selectors: #header, #main, #submit. Each one adds 1. The class column counts class selectors, attribute selectors like [type=”text”], and pseudo-classes like :hover, :focus, and :nth-child(). Each adds 1. The element column counts element names like div and p, and pseudo-elements like ::before and ::after, including the legacy single-colon forms :before and :after. Each adds 1.

The universal selector * adds nothing, which is why * { margin: 0 } loses to everything. Combinators, the spaces, >, +, and ~ between parts of a selector, also add nothing: they describe relationships, not targets. A selector like ul li a scores (0, 0, 3) purely from its three elements, no matter how the parts are connected.

Special Cases: Not, Is, and Where

Three pseudo-classes have special scoring rules, and they confuse people regularly. :not() adds the specificity of its argument: :not(.card) scores (0, 1, 0), the same as .card itself, while the :not itself adds nothing. :is() takes the highest specificity among its arguments: :is(#main, .card) scores (1, 0, 0), because the ID argument wins. :where() always scores zero, no matter its arguments, which makes it the tool for writing low-specificity defaults that any later rule can override.

These rules matter in real code. A reset stylesheet written with :where() stays overridable by ordinary classes, which is exactly what a reset should do. A component library that scopes styles with :is() can accidentally create high-specificity selectors from one ID argument, making its styles hard to override. Knowing the rule lets you choose the right pseudo-class deliberately instead of discovering its cost later.

Inline Styles and Important

Two things sit outside the three-column score. Inline styles, written in a style attribute, beat every selector, because they are treated as a higher column of their own. The !important flag beats everything except another !important, with specificity breaking ties among important rules. Both are escape hatches, and both create the same problem: they make future overrides harder, because the next developer must use an even stronger escape hatch.

The practical advice is to avoid both unless there is no alternative. Inline styles belong to dynamic values set by JavaScript, not to design rules. !important belongs to user stylesheets, utility overrides, and third-party code you cannot otherwise control. A codebase where !important is common is a codebase where specificity has already been lost, and the fix is to lower scores across the board, not to add more flags.

Keeping Specificity Low

The healthiest CSS habit is to keep specificity flat and low: mostly single classes, occasionally two, almost never IDs for styling. When every rule scores (0, 1, 0) or (0, 2, 0), order decides conflicts, and order is easy to reason about: later wins. When scores vary wildly, order stops mattering and only calculation explains the result, which is where the mystery bugs live.

Common Mistakes

The most common mistake is fighting specificity by adding more of it: a rule loses, so the developer writes a longer selector, which wins today and becomes tomorrow’s mystery. The better fix is usually to find the winning rule and lower its score, or to move your rule later in the stylesheet when scores tie. Another mistake is counting columns as a single number incorrectly: (0, 2, 0) is not “20” in a way that compares with (1, 0, 0) as “100” by accident; the column rule is exact, and ten classes never beat one ID.

Related tools

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top