loot.tools

CSS Specificity Calculator

Figure out why one CSS rule beats another. Specificity is the score a browser uses to break ties when several rules target the same element, and it trips people up constantly. Paste one or more selectors, one per line, and this tool breaks each down into the standard three-part score: IDs, then classes/attributes/pseudo-classes, then element types and pseudo-elements. It handles the tricky cases too - :not(), :is(), and :has() take their most specific argument, :where() always scores zero, and the universal selector and combinators add nothing. When you list several selectors it highlights which one takes priority. Everything runs in your browser.

Work out the specificity of any CSS selector. Specificity is the score the browser uses to decide which rule wins when several target the same element. Put one selector per line to compare them and see which one takes priority.

  • #header .nav aspecificity 1,1,1wins
    1ID
    1Class
    1Type
  • nav ul li aspecificity 0,0,4
    0ID
    0Class
    4Type
  • .nav a.linkspecificity 0,2,1
    0ID
    2Class
    1Type
How the score reads
  • ID - counts every #id selector.
  • Class - counts classes, attribute selectors, and pseudo-classes like :hover.
  • Type - counts element names and pseudo-elements like ::before.

Compare left to right: any ID beats any number of classes, and any class beats any number of type selectors. The universal selector * and combinators add nothing.

How specificity works

Every selector gets a three-part score written a,b,c. The 'a' column counts ID selectors, 'b' counts classes, attribute selectors, and pseudo-classes, and 'c' counts element types and pseudo-elements. The browser compares the columns left to right: a single ID beats any number of classes, and a single class beats any number of element selectors. When two rules tie on specificity, the one that comes later in the stylesheet wins.

The cases people get wrong

  • :not(), :is(), and :has() don't add anything themselves - they take the specificity of their most specific argument, so :is(#id, .class) scores as an ID
  • :where() is the escape hatch: it always scores zero no matter what's inside, which makes it great for low-priority base styles
  • The universal selector * and combinators (>, +, ~, and the descendant space) add nothing
  • Inline styles and !important sit above all of this

Why it matters

Reaching for !important to force a style usually means a specificity fight you can win more cleanly. Score your selectors here, see exactly what's outranking what, and adjust the one that's losing instead of nuking it. Keeping specificity low and flat makes a stylesheet far easier to override and maintain.