CSS specificity and the cascade

A recent Twitter poll has caused a bit of a storm and there’s something important to take away from it: there’s a gap in some folk’s CSS skillsets, so I’ll try to help y’all fill it in.

Let’s not dwell on on the hot drama and instead, dive in and have some fun by learning.

The example at hand

Let’s use the same example as the Twitter poll. I’ve used background instead of color and used some nicer colors, rather than the default red and blue ones.

This is what we get:

See the Pen CSS specificity and the cascade: example 1 by Andy Bell (@hankchizljaw) on CodePen.

As you can see, both boxes are blue. But why is that? The reason is that both .red and .blue have the same specificity level as each other, so the browser picks the one that was declared last. In this case, that was .blue.

If we were to switch the two classes over in the CSS, we’d end up with this:

See the Pen CSS specificity and the cascade: example 2 by Andy Bell (@hankchizljaw) on CodePen.

Because .red was declared after .blue, the boxes are red. This is thanks to the fact that the browser cascades down the stylesheet looking for the most specific rule. The rules that were found were of equal specificity to each other, so .red coming after .blue means the boxes are going to be red.

A basic introduction to specificity

Let’s use this same example to demonstrate some simple, common specificity situations and approaches.

Use an ID

This is probably one of the most common ways that folks will give something a specificity boost. An id will take precedence over a class, so in the below example, the new CSS rule #green will override both .red and .blue, regardless of their order in the CSS file.

I will use this example as an opportunity to mention that the use of IDs in CSS is totally valid, but I’d recommend cautious usage. Attaching styles to classes, HTML elements and attributes gives you a lot more flexibility.

Example:

See the Pen CSS specificity and the cascade: example 3 by Andy Bell (@hankchizljaw) on CodePen.

Add a style attribute

Let’s follow on from the id example and override it. One way we can do that is add a style attribute to the element. This will override the #green rule because style attributes take precedence over any rule defined in a CSS file, apart from !important (we’ll get to that).

The following example shows that because I set the background to be purple on the #green element in a style attribute, it overrode all of the other styles (including those defined in .red and .blue).

Example:

See the Pen CSS specificity and the cascade: example 4 by Andy Bell (@hankchizljaw) on CodePen.

Add an !important

Last-up in this basic introduction is !important. This is the CSS equivalent to an articulated lorry on a country lane: it will win in pretty much any scenario.

This example, that follows on from the style example, shows that if I add !important to the background declaration in the .red class, all the boxes turn red. This is because !important takes ultimate precedence. Use !important wisely, though. Because of its importance it becomes difficult to override. Oftentimes the use of !important indicates that there’s probably some refactoring required.

Example

See the Pen CSS specificity and the cascade: example 5 by Andy Bell (@hankchizljaw) on CodePen.

Wrapping up

Hopefully, this little post helps you understand both why the answer to the Twitter poll was blue and how cascade and specificity work on a basic level.

Understanding the cascade and specificity in CSS is really important and that knowledge will make you a better front-end developer. Knowing fundamentals about the web platform will help you to make better, more informed decisions that will likely result in more graceful, resilient problem solving. This will of course have a much more positive impact on the people that really matter: your website’s visitors.

Further reading