Image credit: Oleksandr Hruts

I’m a few days into my learning journey with the Odin project and I can say that I’ve learnt so much within a short space of time.

I’ve been introduced to basic HTML and I have even built my first project (a recipe page) https://github.com/Chiza1/odin-recipes. Well, the page isn’t looking like most of the web pages you’ve seen out there but I’m super proud of myself for accomplishing this milestone in less than a week of learning to code. 

Next, I was introduced to CSS and this was where it got really interesting. It was easy to grasp most of the concepts – selector types and syntaxes, and the different methods of adding CSS to an HTML document but I struggled to understand cascading and specificity. At one point, I had to shut down my PC and returned to it the next day. 

I consulted external materials, read the recommended materials over and over, and finally, I was able to understand what they were talking about. 

In order to deepen that understanding, I decided to write about it. 

So in this article, I’m going to be sharing what I understood about cascading and specificity. Yeah, it’s literally going to be exactly that – “WHAT I UNDERSTOOD”.and  in my own language. This might be beneficial to you if you are also just coming across this concept and struggling to understand it. 

What is cascading in CSS? 

The CSS cascade is like an algorithm or model that determines which CSS rule gets applied to an HTML element – webdev. It’s just that! It doesn’t need to be more complicated than that. Let’s look at some examples for easier understanding. 

Example 1: 

If we have an HTML h1 element (What is CSS cascade) like the one below 

And we style it with the color red using the type selector. 

We’ll have our h1 styled with the red color just like we want it

But what if we use another selector – say the ‘class’ selector and style it with the color green?

Well, the cascade will override our type selector which is the ‘red color’ and ‘green’ will be applied to our element because the class element is superior or more specific than the class element. 

But why did this happen? 

To understand how the cascade works, you need to, first of all, understand the different CSS selectors available and their specificity hierarchy.  

So there are 6 commonly used CSS selectors.

  1. Universal selector 
  2. Type selector 
  3. Class selector 
  4. Id selector 
  5. Inline selector 
  6. Grouping and chaining selector

We’ll be going over each selector type with some examples for better understanding. 

After we’ve gone through the types of selectors in CSS, we’ll then talk about their hierarchy in the cascade and how to calculate which style is going to be applied to an element in a situation where there are multiple rules targeting one element.

  1. Universal selector: 

The universal selector is used to select any HTML element. It doesn’t matter what type of element/tag is used in the document.  When you apply a style using the universal selector, that style can be applied to all elements in the HTML document. 

In the below screenshot, you’ll notice that both the h1, p, and button tags were colored red because I used the universal selector.  

Things to Note about the universal selector_ 

  1. The type selector: 

The type selector, also known as the element selector, is used to select an HTML element or type. Please note that element. tag, and type are all talking about the same thing.

In the screenshot below, you’ll notice that all (p) tags have been styled with the color blue because I selected all the p tags using the type selector in the CSS file.

Things to note about the type selector_

1 is higher than 0 and so that’s why the type selector will be chosen in this case. But we’ll talk about these values in detail later in this post. 

  1. Class selector:

The class selector is used to select all the elements in a given class. A class is an HTML attribute – A HTML attribute on the other hand is like an extra information added to an HTML element. Hope that makes sense

In the example above, can you see how the (h1) tag has been changed to color black because we declared the color black with a class selector? It literally ignored the universal selector and it would also ignore the type selector if it were selected.

Things to note about the class selector_ 

Take a look at the example below 

Here I added a class attribute to one of the (p) tags and named the class “definition”. I then selected it in the CSS section and gave it a font size of 80px.  I also made the font size in the type selector 40px. By right, all the p tags should have a 40px font size but the class element has overridden the p tag and given it a font size of 80px. 

And that is because the selector with the higher specificity value will always win the race in the cascade. There are some exceptions though. We’ll come to that later too. 

  1. ID selector:

The ID selector has the second to the highest specificity value in the cascade. It is similar to the class selector because it is also an attribute that can be added to an HTML element.

In the screenshot above, I added an ID selector with the name ‘meaning’ to the p tag that already has a class selector and I selected it in CSS and gave it a font size of 10px;  notice how the class selector has been ignored and 10px font size is now given to the p element? 

Things to note about the Id selector_

  1. Inline selector: 

The inline selector isn’t really a selector type, rather, It’s one of the three ways of adding CSS to an HTML document. 

So a CSS sheet can be added in 3 ways, external, internal, and inline.  We won’t go into details on this. I just need you to know some basic things so you can understand the point I want to make

  1. The external method involves having your CSS in a separate file and then linking it to the HTML document using the link attribute
  2. The internal involves adding your CSS style inside the head tag of your HTML document. 
  3. While the inline involves adding the style to an HTML element. 

The inline selector like the name applies – is added within the LINE of the HTML element that we wish to style.

Take a look at the screenshot below

There are 3 things to take note of in the screenshot above

  1. The first (p) tag has 2 different selectors – An ID and an inline selector. 
  2. The id selector has a – background color of black and a text color of white.
  3. While the inline selector has a background color of pink and a text color of red.

Now despite the id selector having a 100 specificity value, the inline selector preceded it. The reason is that the inline selector has a 1000 specificity value. That’s about 10 times the id selector. 

Things to note about the inline selector_

6. Grouping and chaining selector: 

Contrary to what you may think, grouping and chaining selector isn’t really a type of CSS selector but a method that is commonly used to apply CSS rules. Understanding this concept will save you a ton of CSS frustration. 

Grouping and chaining selector simply means combining two or more CSS selectors to elements that share styling rules. 

Initially, I was confused by how grouping and chaining work but with further research and practice, I was able to understand it. 

Grouping selector example: 

In the screenshot below, I used the grouping selector to selector (h1) and (p) tags. 

This is better, faster, and more efficient than this 👇

Chaining selector example 

Things to note about grouping and chaining selectors_ 

What is specificity in CSS? 

Specificity comes from the word – ‘specific’ and it means being precise or being clearly stated. 

So in CSS, the cascade which is an algorithm like we learnt above works by applying the CSS declaration that is more precise. There are certain factors that are taken into consideration to determine this precision and that’s why specificity hierarchy comes into play. 

CSS Specificity hierarchy

Specificity hierarchy refers to how the CSS selector we talked about above is ranked.

The higher the rank, the higher it will preside over the rest.

Take a look at the table below

This section involves some basic mathematics. This is what determines which rule gets applied to an element. If you can understand how the calculation works, you’ll be able to understand why your CSS is not behaving the way you want it to.

Let’s briefly break it down

  1. (p):  You can see that the type selector – which in this case is represented by the p tag has a value of 1. 
  2. (p.test): In this case, the (p) type selector has a value of 1 and it’s been chained with a class selector (.test) which has a value of 10. That makes its total value 11. 
  3. (p#demo): Here the type selector which has a value of 1 is chained to the id selector which has a value of 100. This makes it a total of 101
  4. <p style=”color:pink;”>: as we learnt above, this is an inline selector and it has 1000 values. Making it higher than any grouping or chaining you can ever think of.
  5. (#demo) Remember we said the id selector has a 100 specificity value right? Yeah!
  6. (.test): Class selector has a 10 specificity value
  7. (p.test1.test2) Here the type selector is being combined with two class selectors. Close your eyes and do the math….. It’s 21. It’s that simple!
  8. (#navbar p#demo) This example has two id selectors and one type selector. That makes it a total of 201 specificity values. Got it now?
  9. (*) The last on this list is the universal selector. This selector has a 0 specificity value and will always be overwritten by any higher value such as the type selector.

There you have it. The selector with the highest value will certainly always take precedence over any other. 

So the next time you wonder why your h1 is having the color red instead of green, take out some sheet of paper or your calculator and calculate the value of the selectors that are being applied to it. 

Rule order and the !important value

Before you go, I’d like you to know about the rule order and the !important value because it can also interfere with how your CSS rules behave. 

Rule order

So when the cascade has so many conflicting rules on an element and none of the specificity rules seem to help, it will apply the last declaration to the element. 

Looking at the example below, the button element has two classes with different styling rules, since both selectors are of the same value (10) the cascade had to apply the last declaration. 

The rule order only takes effect when no rule is more specific than others. 

The !important value 

When you use the !important in your CSS declaration, it tells the cascade to only apply that rule and ignore others. The important rule is super powerful in that it ignores even the inline selector that has 1000 specificity values.

If you look at the screenshot above, you’ll notice that I’ve forced the cascade to apply the background-color blue to the button using the !important rule despite having an inline declaration of the color pink.

The !important declaration is so powerful that it’s often advised against using it because it might cause more harm than good. That’s why it’s a good idea to try and understand how the specificity rule works so you won’t find yourself being tempted to use the !important value.

Final thoughts

I hope you enjoy reading this article and that you now have a clearer idea of how cascading and specificity work. 

If you are also learning to code, feel free to reach out to me, and let’s share ideas and learn together. 

Reference

These resources helped me put this article together. 

https://www.w3schools.com/css/css_specificity.asp
https://www.theodinproject.com/lessons/foundations-css-foundations

More info on CSS specificity and cascade

https://wattenberger.com/blog/css-cascade

Leave a Reply

Your email address will not be published. Required fields are marked *