consolelog.tools

CSS Specificity Calculator

Score one or many CSS selectors live as you type. Each gets its spec-accurate (a,b,c) tuple - IDs, classes/attributes/pseudo-classes, and elements/pseudo-elements - with a per-token breakdown showing exactly which piece feeds which column. It handles :is(), :where() (which contributes zero), and :not() correctly, flags !important and inline styles as higher precedence, then ranks every selector and shows which one wins (or ties). Copy or share a full report.

About this ToolHow it works, benefits & use cases

When two CSS rules fight over the same element, specificity decides the winner - and this calculator scores every selector you type, live, the moment you type it. Enter one selector per line and each gets its spec-accurate three-part (a,b,c) tuple: a counts IDs, b counts classes, attribute selectors and pseudo-classes, and c counts elements and pseudo-elements. Every selector is broken down token by token, with colored chips showing exactly which piece feeds which column, so you can see at a glance why one rule outweighs another. It handles modern selectors correctly: :where() always contributes zero, while :is() and :not() take the specificity of their most specific argument. It also flags !important and inline styles, which sit above the tuple entirely in the cascade. All your selectors are then ranked from highest to lowest precedence, the winner is highlighted, and genuine ties are called out so you know source order will break them. A set of canonical reference examples - pre-scored with their tuples - is one click away, and you can copy or share a full plain-text report. Everything runs locally in your browser and the input is captured in a shareable URL.

How to Use

  1. 1Type or paste CSS selectors into the input, one per line - the ranking recalculates on every keystroke.
  2. 2Read each selector's (a,b,c) tuple and the colored token chips showing which piece feeds which column.
  3. 3Check the ranked list to see which selector wins, or whether several tie for the top.
  4. 4Click a reference example to append it and watch how its specificity breaks down.
  5. 5Copy, download, or share the full report with a teammate.

Key Benefits

  • Live, keystroke-by-keystroke scoring of many selectors at once - no run button
  • Spec-accurate (a,b,c) tuples with a per-token breakdown highlighting each contribution
  • Correct handling of :is(), :where() (which scores zero), and :not()
  • Detects and flags !important and inline styles as higher precedence
  • Ranks all selectors highest to lowest and clearly marks the winner (and ties)
  • Curated, pre-scored reference examples from trivial to deliberately complex
  • Copyable, shareable report and a URL that captures the exact input

Common Use Cases

  • Debugging why one rule overrides another in a stylesheet
  • Comparing several competing selectors at once before editing
  • Deciding whether to add an ID or refactor to keep specificity low
  • Teaching how the CSS cascade weighs IDs, classes, and elements
  • Auditing legacy CSS where overly specific selectors cause conflicts
Winner

#header .nav li a:hover wins with the highest precedence (1,2,2).

Ranked by specificity
  1. #header .nav li a:hover
    1,2,2
    #header.navlia:hover
  2. :is(#main, .content) p
    1,0,1
    :is(#main, .content)p
  3. .nav a
    0,1,1
    .nava
  4. ul li a
    0,0,3
    ullia
a · IDs b · classes / attrs / pseudo-classes c · elements / pseudo-elements

Copy, download, or share the full ranking

CSS Specificity Report
======================
Notation: (a,b,c) = (IDs, classes/attributes/pseudo-classes, elements/pseudo-elements)

Ranked highest -> lowest precedence:

1. (1,2,2)  #header .nav li a:hover  <- winner
2. (1,0,1)  :is(#main, .content) p
3. (0,1,1)  .nav a
4. (0,0,3)  ul li a

Per-selector breakdown:

  #header .nav li a:hover  ->  (1,2,2)
    - #header  -> a (ID)  [ID]
    - .nav  -> b (class/attr/pseudo)  [class]
    - li  -> c (element/pseudo-el)  [element]
    - a  -> c (element/pseudo-el)  [element]
    - :hover  -> b (class/attr/pseudo)  [pseudo-class]

  :is(#main, .content) p  ->  (1,0,1)
    - p  -> c (element/pseudo-el)  [element]

  .nav a  ->  (0,1,1)
    - .nav  -> b (class/attr/pseudo)  [class]
    - a  -> c (element/pseudo-el)  [element]

  ul li a  ->  (0,0,3)
    - ul  -> c (element/pseudo-el)  [element]
    - li  -> c (element/pseudo-el)  [element]
    - a  -> c (element/pseudo-el)  [element]

Result: "#header .nav li a:hover" wins with the highest precedence.

One selector per line — specificity updates live

Reference examples

Click any example to append it to the input and see how it scores.

How specificity is scored

Each selector gets a three-part (a,b,c) tuple. The a column counts IDs, b counts classes, attribute selectors and pseudo-classes, and c counts elements and pseudo-elements. Columns are compared left to right, so a single ID always beats any number of classes.

:is(), :where() and :not()

:where() always contributes zero, which makes it perfect for low specificity resets. :is() and :not() take the specificity of their most specific argument. !important and inline styles sit above the tuple entirely and are flagged as such.

Was this tool helpful?

Share Your Experience

Help others discover this tool!

Related tools