Google Sheets iconSwift icon
Published at
Updated at
Reading time
5min

The CSS cascade and the closely related topic of CSS selector specificity are often misunderstood in the web development community. Unfortunately, my impression is that many developers never learned how CSS really works.

Trending solutions such as "CSS-in-JS" and Tailwind are definitely not helping with the overall understanding of this core web technology. The missing knowledge brings up the following questions:

Will it become less critical to know CSS in the future? I don't know, maybe one day... probably not...

Do I think that it's essential to understand how browsers apply styles today? Absolutely!

Side note: I'm not favoring or am advising to use any CSS solution out there. I prefer less complex frontends these days, but you do you!

I was thinking about developer education over the last few days and couldn't get the idea of teaching the cascade in the developer tools out of my head. This post proposes a small developer tools addition that I believe could help more developers understanding CSS.

CSS specificity in a nutshell (super quick)

Let's have a very quick and not complete CSS specificity refresher. If you want to learn more on the topic, read this MDN article about the CSS cascade or the CSS cascading specification.

If multiple CSS selectors and rules match the same HTML element, what styles should be applied? What should happen in a codebase when there a five different color declarations for the h1 element?

This problem is where the CSS cascade and selector specificity comes into play. CSS declarations are applied depending on where they are defined. Are inline styles specifying the red color? Is the blue color set in a highly complex selector in the main stylesheet? Various factors play a role in figuring out what styles to apply. Generally speaking, the most specific declaration wins.

To understand how browsers calculate the CSS specificity have a look at the CSS spec. There are three different components to consider:

  • the number of ID selectors in a CSS selector (= A)
  • the number of class selectors, attributes selectors, and pseudo-classes in a CSS selector (= B)
  • the number of element type selectors and pseudo-elements in a CSS selector (= C)

These three numbers have different weights and lead combined to the selector specificity value (e.g. 0 x A, 1 x B, 0 x C = 0,1,0).

A selector including an id is always more specific than a class selector (1,0,0 > 0,1,0). A selector including a class or attribute is always more specific than an element selector (0,1,0 > 0,0,1).

If you're dealing with multiple selectors that define the same property on the same element, the one with the highest specificity wins and its styles are applied.

/* 
  Consider this element:
  <div class="class-selector" id="id-selector">
    Hello world!
  </div>
*/ 

/* 
  Specificity: 0 x A, 0 x B, 1 x C -> 0,0,1
  (because there's an element in the selector)
*/
div {
  color: red;
}

/* 
  Specificity: 0 x A, 1 x B, 0 x C -> 0,1,0
  (because there's a class in the selector)
*/
.class-selector {
  color: blue;
}

/* 
  Specificity: 1 x A, 0 x B, 0 x C -> 1,0,0
  (because there's an id in the selector)
*/
#id-selector {
  color: yellow;
}

No matter the order of these three CSS selectors, the div's text color will be yellow because the #id-selector has the highest specificity (1,0,0).

But how do people learn how this works, then?

The importance of education in developer tools

I wrote about the importance of DevTool warnings two years ago, and I still believe that browser developer tools play an essential role in developer education. Web development includes many different areas, so it's tough to learn what's necessary to build websites with an outstanding user experience. At the end of the day, you can't know what you don't know.

Developer tools improved significantly over the last few years. Google Chrome's Lighthouse monitoring tool became a defacto standard in measuring a website's quality. It shows areas of improvement and consistently links to additional resources.

Lighthouse report providing URLs to further reading material

Firefox started to give valuable hints in the CSS tools explaining when and why CSS declarations aren't working.

Firefox devtools telling that the CSS property doesn't make sense.

As you see, developer tools take on the task of educating developers today. Wouldn't it be great to explain about the cascade, too?

Can we have "Learn more" resources for the CSS cascade?

When you're working on a large codebase and are dealing with a non-trivial amount of CSS, you often find many competing CSS declarations. Multiple selectors overwrite each other. When you inspect the applied element styles in the developer tools, they show you which styles are applied and which ones are overwritten.

CSS Developer Tools showing crossed values when they're overruled by another selector.

Overwritten styles are crossed out, and this is great, but that's almost all you get. There's no additional information on why one property is applied while another one isn't.

Today I learned that there is another view in the DevTools that shows the ranking of the selectors and matching properties inside the "computed" panel. That is a great first step!

Developer tools computed panel that shows the applied declarations ordered by specificity.

The computed property details list all the matching styles. The list is ordered by the specificity of their selectors. Unfortunately, this view isn't explaining the list's order and I think that's a missed opportunity.

Wouldn't it be nice if this view shows the selector specificity and provides additional resources on the CSS cascade?

Proposal for devtools explaining the Cascade and showing selector specificity.

I think that the above additions could help to educate developers about CSS tremendously. The only downside I can think of is that additional information might overwhelm developers, but I would take that risk in favor of more people learning CSS properly.

What do you think about this proposal? Is there something like that in the making from a browser vendor side? I'd love to have a conversation on the topic. Feel free to drop me an email or reach out on Twitter.

Edit #1: It turns out that the web development browser Polypane shows the specificity values. 👏

Edit #2: Thomas Steiner agreed with this article and filed a Chromium bug. Go ahead and give it a star, if you like.

Related Topics

Related Articles