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
#idinto the first slot, and.class,[attr]and:pseudo-classinto the second. - Count element names and
::pseudo-elementsinto 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
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.