Every web developer has lived through the same baffling moment: you write a CSS rule, you are certain it targets the right element, you reload the page, and nothing changes. You add another rule, more forceful this time, and still nothing changes. You add an exclamation mark of desperation — the infamous !important — and finally the style applies, but now you have created a new problem for the next person who needs to override it. The root cause, in almost every case, is specificity: the system by which browsers decide which rule wins when several rules target the same element. It is a precise, learnable system, and once you understand it, those baffling moments largely disappear.

The CSS Specificity Calculator makes the system visible. You type a selector, and it returns the specificity as three counts — IDs, classes, and elements — plus a comparison score. Those three numbers are the whole story. Learn to read them, and you can predict which rule will win before you write it, rather than discovering the winner by trial and error.

How the tool works

Specificity is counted in three categories, conventionally written as (a, b, c). The first number, a, counts ID selectors, such as #main. The second number, b, counts class selectors, attribute selectors, and pseudo-classes, such as .card, [type="text"], and :hover. The third number, c, counts element selectors and pseudo-elements, such as p, div, and ::before. The universal selector, *, and combinators such as spaces and greater-than signs, contribute nothing to specificity.

Comparison works from left to right, like comparing numbers by their most significant digit first. A selector with more IDs beats any selector with fewer IDs, regardless of how many classes or elements the other selector has. If the ID counts are equal, the class counts decide. If those are also equal, the element counts decide. If all three counts are equal, the rule that appears later in the stylesheet wins. That ordering is absolute: no number of classes can outweigh a single ID, and no number of elements can outweigh a single class.

The calculator's comparison score is a convenience for sorting, but the three counts are the authoritative view. A score can mislead if you treat it as a single decimal number — for example, if a selector somehow accumulated more than nine classes, a naive score would carry over into the next column — so always read the (a, b, c) triple itself when the result matters.

A worked example

Take the selector #main .card p. It contains one ID (#main), one class (.card), and one element (p). Its specificity is therefore (1, 1, 1): one ID, one class, one element.

Now take the selector .nav a:hover. It contains no IDs, two class-level selectors (.nav and the pseudo-class :hover), and one element (a). Its specificity is (0, 2, 1): zero IDs, two classes, one element.

Compare the two. The first selector has one ID and the second has none, so the first selector wins, regardless of the second selector's two classes. That is the rule that surprises beginners most: a single ID outweighs any number of classes, so a rule written with an ID is very hard to override without another ID or an !important declaration.

A second comparison shows the class level at work. Compare .card p, with specificity (0, 1, 1), against .nav .card a, with specificity (0, 2, 1). Both have zero IDs, so the class counts decide: two classes beat one class, so the second selector wins, even though the first appears in the stylesheet later or earlier — order only matters when specificity is exactly equal. And a third comparison shows the element level: p, with (0, 0, 1), loses to div p, with (0, 0, 2), because two elements beat one element when IDs and classes are tied.

These examples explain the practical advice that experienced developers give: prefer classes, avoid IDs in CSS, and keep selectors short. A stylesheet built from single classes has low, even specificity throughout, so rules can be overridden predictably by adding one more class or by source order. A stylesheet built from long, ID-heavy selectors creates a specificity arms race, where every override must be more specific than the last, and the stylesheet grows ever more tangled.

Common mistakes

The first mistake is reaching for !important as a first resort. The !important declaration overrides specificity entirely, which feels like a solution, but it creates a new layer of conflict: the next override needs !important too, and soon the stylesheet is full of declarations that cannot be overridden at all without further !important flags. Reserve !important for genuine exceptions, such as utility classes that must always win, and fix specificity problems by writing a properly specific selector instead.

The second mistake is counting pseudo-classes as elements. Hover, focus, first-child and similar pseudo-classes count at the class level, not the element level. A selector such as a:hover has specificity (0, 1, 1), not (0, 0, 2), and that extra class-level weight is why hover rules often win over plain element rules in ways that surprise their authors.

The third mistake is assuming that inline styles and stylesheet rules compete on the same scale. An inline style, written directly on an element, beats any stylesheet selector, regardless of specificity, unless the stylesheet rule carries !important. If a style refuses to apply and you cannot see why, check for an inline style on the element itself before questioning your specificity arithmetic.

The fourth mistake is writing overly long selectors "to be safe". A selector such as body div#main section.content article.post p.text is extremely specific, which means it is also extremely hard to override and tightly coupled to the page structure. If the structure changes, the selector breaks. Short, class-based selectors are more robust, more reusable, and easier to override, which is why they are the professional default.

Honest limitations

The calculator counts specificity correctly, but specificity is only part of the cascade. Source order, inheritance, the origin of the stylesheet, and !important declarations all affect which style finally applies, and a selector with higher specificity can still lose to a later rule with !important, or to a user stylesheet in certain contexts. The tool also cannot see your stylesheet as a whole: it evaluates one selector at a time, so it cannot tell you which of your many rules actually conflict on a given element. For that, browser developer tools, which show the matched rules and strike through the losers, remain the best diagnostic.

Closing

Read every selector as (IDs, classes, elements), compare from left to right, prefer classes over IDs, keep selectors short, and save !important for true exceptions. To tidy the stylesheet where those selectors live, try the CSS Formatter and Beautifier, and to settle which element sits above another once styles apply, see the CSS Z-Index Generator. For fixing stacking order problems specifically, read CSS Z-Index Generator: Fix Stacking Order Fast.