CSS Specificity Calculator

Calculate the specificity of any CSS selector as an (a, b, c) score.

Free CSS specificity calculator. Paste any CSS selector to get its (a, b, c) specificity score — IDs, classes/attributes/pseudo-classes, and elements/pseudo-elements — with handling for :is(), :not(), :has() and :where(). Runs entirely in your browser — nothing is uploaded. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

Is my selector sent to a server?

No. The selector is parsed entirely in your browser with plain JavaScript. Nothing you type is uploaded anywhere.

CSS specificity decides which rule wins when several target the same element, and getting it wrong is a common cause of “why won’t my style apply?” bugs. This calculator parses any CSS selector and reports its (a, b, c) specificity score, with a breakdown explaining each part — so you can predict which rule the browser will honour.

How it works

Specificity is a three-part score compared left to right:

  • a counts ID selectors (#id).
  • b counts classes, attribute selectors ([type="text"]) and pseudo-classes (:hover).
  • c counts element types (div) and pseudo-elements (::before).

A higher a always beats any b, which always beats any c — so a single ID outranks any number of classes. The calculator also handles modern functional pseudo-classes: :is(), :not() and :has() take the specificity of their most specific argument, while :where() always contributes 0. These rules are noted in the breakdown.

Worked examples

Simple example — #nav .item a:

PartSelector componentContributes to
#navIDa +1
.itemClassb +1
aElement typec +1

Score: (1, 1, 1). Beats .item .link a — which scores (0, 2, 1) — because the single ID in column a outranks any number of classes.

Functional pseudo-classes — :is() and :not():

The selector :is(#header, .nav) a takes the specificity of the most specific argument inside :is(). Here that is #header (an ID), so the score is (1, 0, 1) — not (0, 1, 1) as you might expect from reading .nav. This is the main specificity gotcha with :is().

By contrast, :where(#header, .nav) a always contributes zero from the :where() part, giving a score of (0, 0, 1). This makes :where() ideal for base styles that should be easy to override.

Specificity of !important: !important does not change the (a, b, c) score — it operates at a completely separate level above specificity, overriding any competing declaration regardless of score. Two !important rules competing with each other are resolved by specificity, but an !important rule beats every normal rule.

Common specificity traps

Using an ID when a class would do. IDs cannot be overridden by any number of classes, which makes debugging difficult. Reserve IDs for anchor links and JavaScript hooks; use classes for styling.

Qualifying a class with an element. div.card scores (0, 1, 1), higher than .card at (0, 1, 0). This means div.card cannot be overridden by another class alone. Remove the element qualifier: just .card.

Inline styles beat everything normal. style="color: red" is equivalent to (1, 0, 0, 0) — a fourth column above IDs that no selector wins against in normal flow. Only !important can override an inline style.

The universal selector contributes zero. * .item scores (0, 1, 0), the same as .item — the * adds nothing.

Everything is parsed in your browser, so nothing is uploaded.