Charts · 15

Specificity, three columns

Your override is there, it is later in the file, and the button still ignores it. Specificity is not a score, it is three separate counts compared left to right: ids, then classes and their kin, then types. One id outranks any number of classes; one class outranks any number of element names. Add the rules that target one button and see which one the browser will pick, and the seven things that get a say before specificity even comes up.

  1. .btn010(0,1,0)
  2. .card .btn020(0,2,0)
  3. #app .btn110(1,1,0)
  4. .btn.btn020(0,2,0)
  5. :where(.card) .btn010(0,1,0)

ids · classes, attributes, pseudo-classes · types, pseudo-elements. Compared left to right; a single id beats a hundred classes. Ties go to the rule that comes last, so order in the list is source order.

Notes

Computed by a small parser rather than a lookup: ids count in the first column; classes, attribute selectors and pseudo-classes in the second; type selectors and pseudo-elements in the third. The universal selector and combinators count nothing. :is(), :not() and :has() take the specificity of their most specific argument; :where() always contributes zero, which is the whole reason it exists; :nth-child(An+B of S) counts as one pseudo-class plus S. The legacy single-colon forms of :before and :after are treated as pseudo-elements, as browsers do. Cascade order is from CSS Cascading and Inheritance Level 5: transitions, then importance and origin, then layers, then the style attribute, then specificity, then order of appearance. Source: Selectors Level 4, section 17, Calculating a selector’s specificity; CSS Cascade 5, section 6.