AniUI Academy
hard+350 XPPractice

Score CSS selector specificity

"Why isn't my style applying?" is nearly always specificity. Being able to score a selector by hand is what turns that question into a two-second answer, and linters and CSS-in-JS tools compute exactly this triple.

Implement specificity(selector) returning [a, b, c], where a counts id selectors, b counts class selectors, attribute selectors and pseudo-classes, and c counts type (element) selectors and pseudo-elements. Assume a single selector with no commas.

Count each #id into a. Count each .class, each [...] attribute selector, and each single-colon pseudo-class such as :hover or :nth-child(2n+1) into b; the arguments of a functional pseudo-class are ignored. Count each type selector such as div and each double-colon pseudo-element such as ::before into c. The universal selector * and the combinators >, +, ~ and descendant whitespace count for nothing.

:not(), :is() and :has() add nothing for themselves, but the selectors written inside their parentheses are counted as if they appeared in their place — so li:not(.active) scores [0, 1, 1]. Note that anything inside an attribute selector, including a # in [href^="#"], is part of the attribute selector and is never counted separately.

What it has to do

  • Return a three element array [ids, classes, types] of numbers.
  • Count #id into the first slot, and .class, [attr] and :pseudo-class into the second.
  • Count element names and ::pseudo-elements into the third.
  • Score * and all combinators as zero.
  • Ignore :not(), :is() and :has() themselves but count the selectors inside them, and never count characters inside an attribute selector.

Your workspace

Try it yourself
Loading playground...

Ready to check it?

5 tests run against your code, right here in your browser. Sign in to claim the XP when you pass.

AI Crack & Solution Assist

Stuck? Get instant AI hints or break down the optimal solution.

Stuck? The javascript course covers everything this challenge needs.