Specificity

  • Specificity
  • Tips
  • Test yourself
  • The cascade
  • Developer Tools

rvsp.github.io/CSS/selectors/specificity.html

Specificity

Specificity (SpeciFISHity)

Download

Specificity (SpeciFISHity)

Download

Specificity: How it works

  • 0-0-0: Global selector
  • 0-0-1: Type Selector (Elements & pseudoelements)
  • 0-1-0: Class selector (Also attribute selector & pseudoclass)
  • 1-0-0: ID selector
  • 1-0-0-0: inline styles
  • 1-0-0-0-0:
    !important
    (on value)

The HTML

  <body class="blue" id="myPage">
    <div id="someId">
      <article class="home">
        <p class="important">
          <a href="index.html" class="classy" id="anotherID">
            Link
          </a>
        </p>
      </article>
    </div>
  </body>

The CSS

body.blue div#someId a#otherId.classy {
  color: blue; }
#myPage #someId article.home p.important a {
  color: red; }

Specificity: How it works

body.blue div#someId a#otherId.classy {
  color: blue; }
#myPage #someId article.home p.important a {
  color: red; }
  1. How many IDs in the selector?
  2. How many class, attribute and pseudoclasses?
  3. How many type/element or pseudo-elements?
2-X-X
X-2-X
X-X-3

Specificity: The less than obvious

The * selector, or global selector, has a specifity of 0.

Combinators, like ~, >, spaces, and + have no value

ul li {} 0-0-2
ul > li {} 0-0-2

:not has no value, but parameter selector does

.myClass:not(p) {} 0-1-1

Specificity v Inheritance

Specificity is not inheritance

p#myP.important { 
  color: red !important;
}
a {
  color: purple;
}
<p class="important" id="myP">Paragraph with a <a href="x.html">link</a></p>

Paragraph with a link

Styles for a directly targeted element take precedence over inherited styles regardless of inherited specificity.

Parameters

:not(a, .b, #c)
:not(a, .b, #c)
:is(a, .b, #c)
:where(a, .b, #c)
:nth-child(-n + 3 of a.b#c) /* 1-2-1 */

Avoid !important

Hacking specificity

.disabled {cursor: default !important;}
p.btn {cursor: pointer;}

v.

.disabled.disabled.disabled {cursor: default;}
p.btn {cursor: pointer;}

Hacking specificity with IDs

#TheirWidget {background-color: blue !important;}
#3rdPartyWidget {background-color: white;}
v.
#TheirWidget#TheirWidget {background-color: blue ;}
#3rdPartyWidget {background-color: white;}

Hack in case of emergency

a:not(#idDoesNotExist#idDoesNotExist#idDoesNotExist) 

Math Class!

Let's practice

!Even More Important

The Cascade

The Cascade

  1. Transition declarations
  2. Important user agent declarations
  3. Important user declarations
  4. Important author declarations
  5. Animation declarations
  6. Normal author declarations
  7. Normal user declarations
  8. Normal user agent declarations

When multiple declarations have equal specificity, the last declaration found in the CSS is applied to the element.

DevTools

There are extensions that enable you to see the weight of a selectors. But, by default, you can inspect which property value has won out and which selectors lost the specifity battle in the computed section in DevTools, but the selectors are ordered in specifity order.

  • The Rules show the cascade by crossing out properties that were overwritten
  • The computed styles show the final value impacting the selected element, with all values / selectors that were deprioritized.

Generated Content

Next ➹