1

So I've been trying to wrap my head around CSS specificity and it seems to me that the way the formula works it's:

10^0 * (# of element + pseudo element selectors) + 10^1 * (# of classes + attributes + pseudo class selectors) + 10^2 * (# of id selectors) + 10^3 * (inline selectors)

So, for an experiment, I created an HTML page where there are 12 nested element selectors applying to a bit of text, and one class selector. In this case, it seems like the many element selectors should override the single class selector, yet they do not. This example renders the text in red if the element selector wins, and green if the class selector wins.

What's going on? Have I misunderstood the specificity formula? Does a single class selector always win over an arbitrary number of element selectors? Is this why id selectors are considered a code smell, because they will override an arbitrary number of attribute and class selectors?

html > body > main > article > section > form > div > figcaption > div > p > span > em {
      color: red;
    }

    html body main article section form div figcaption div p span em {
      color: red;
    }
    
    .test {
      color: green;
    }
<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
  </head>

  <body>
    <main>
      <article>
        <section>
          <form>
            <div>
              <figcaption>
                <div>
                  <p>
                    <span>
                      <em class="test">TESTING 123</em>
                    </span>
                  </p>
                </div>
              </figcaption>
            </div>
          </form>
        </section>
      </article>
    </main>
  </body>
</html>
Ted Yavuzkurt
  • 475
  • 4
  • 10
  • Give this article a quick read: https://www.smashingmagazine.com/2007/07/css-specificity-things-you-should-know/ – TylerH Mar 16 '17 at 19:20

3 Answers3

4

you are confusing things,

your specificity for your selectors are:

html > body > main > article > section > form > div > figcaption > div > p > span > em 

0,0,0,12


html body main article section form div figcaption div p span em

0,0,0,12


.test

0,0,1,0


Debunking those 4 levels: 0,0,0,0

  • 1st level - inline styles
  • 2nd level -IDs
  • 3rd level - Classes, attributes and pseudo-classes
  • 4th level - Elements and pseudo-elements

Why text is green?

Because you only are using HTML elements, which in the specificity level is the lowest important(4th). Therefore class is more specific which make the text always green

take a look:

SS

Calculate specificity here

See more info about specificity om W3C

Community
  • 1
  • 1
dippas
  • 49,171
  • 15
  • 93
  • 105
4

Does a single class selector always win over an arbitrary number of element selectors?

That's exactly it. Essentially, you have to think in a number system with an "arbitrarily large base". That is, 12 element selectors gives you a specificity that could be described as "0-0-0-12", which doesn't translate to "0-0-1-2", as the base of the number system is not 10.

And yes, this is one of the reasons people recommend avoiding ID selectors.

Here is a piece of relevant specification, although I don't really think their example does anything to help clarify this issue...

klumme
  • 598
  • 2
  • 8
1

Think of the Olympics. What's better:

  • Five bronze medals or one silver?
  • Three silver medals or one gold?

Personally, I would take the one silver and one gold over the alternatives.

That's kind of how specificity points are categorized.

From the spec:

9. Calculating a selector's specificity

A selector's specificity is calculated as follows:

  • count the number of ID selectors in the selector (= a)
  • count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)
  • count the number of type selectors and pseudo-elements in the selector (= c)

Concatenating the three numbers a-b-c (in a number system with a large base) gives the specificity.

emphasis mine

In other words, both the number and concatenation matter.

Therefore, the element selector:

 0 0 12

is less than the class selector:

 0 1 0

The class wins (1 Silver vs 12 Bronze).

You could have 100 element selectors and the class would still win.

Michael Benjamin
  • 265,915
  • 79
  • 461
  • 583