DEV Community

Cover image for CSS Cascade, Specificity, and Selectors
Stephanie-dev
Stephanie-dev

Posted on

CSS Cascade, Specificity, and Selectors

Have you wondered why certain CSS rules you apply, be it inline, internal or external, do not reflect on your live server/website as a newbie, even as a knowledgeable techie?

I have wondered too, don't worry.

We'll be delving into various terminologies and rules that apply to CSS. It might be a lot but with time, you will understand....like I did.

First, let's look at what CSS means.

CSS means Cascading Style Sheets. It is a language used to style your markup document or page, also known as HTML (Hyper Text Markup Language) page.

We have three types of CSS. They are:

  1. Inline CSS
  2. Internal CSS
  3. External CSS
  • Inline CSS: This is the CSS or style applied to a unique element in your HTML document.

For example,

In your HTML document, you have:

<h1>This is a document</h1>
Enter fullscreen mode Exit fullscreen mode

How do you apply your inline CSS?

<h1 style="color:red;">This is a document</h1>
Enter fullscreen mode Exit fullscreen mode

This style="color:red;" tells the browser that the text in the <h1> element should be red.

  • Internal CSS: This defines a style for a single HTML page. It is usually defined in an HTML page's <head> section, within a <style> element.

Example,

<html>
<head>
<meta charset="utf-8">
<style>
       h1{
             color:red;
          }
</style>
</head>
</html>

Enter fullscreen mode Exit fullscreen mode
As you can see, instead of your CSS being in the body of your HTML document like the Inline CSS, it is in the <head> section instead. This way, you can target all the elements you want to style in the <style> tag.
This is also recommended if you want to style your HTML documents separately.
  • External CSS: This styles multiple HTML pages with a single style sheet linked to your HTML page with a <link> tag. Your CSS rules are contained in a separate CSS file with a .css extension. It must be linked to your HTML document to see the results.

Example,

<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="styles.css">
<style>
       h1{
             color:red;
          }
</style>
</head>
</html>
Enter fullscreen mode Exit fullscreen mode

I know these, why are my CSS rules not applying?

Don't worry, we're here.

Since we know what CSS is now, we will look at what CSS Cascade means.

Cascade is the algorithm for solving conflicts where multiple CSS rules apply to an HTML element. This means it reconciles and applies the rules you declare for an element based on some factors.

Understanding how the cascade algorithm works helps you understand why your codes aren't working and how the browser resolves such conflicts.

The cascade algorithm is divided into four (4) stages.

First stage - Position and order of appearance

This is simply the order in which your CSS rules appear.

Example,

h1{
   Color:red;
  }

h1{
   Color:red;
  }
Enter fullscreen mode Exit fullscreen mode

In this case, we have two <h1>elements (selectors of identical specificity) telling the browser to apply certain colors to their texts. The browser will only obey the second rule and ignore the first since it's the last one to be declared.

This can also apply to your internal CSS, inline CSS, and linked stylesheets.

Some frontend developers often have two linked stylesheets in their HTML document or page. In this case, the browser picks the last linked stylesheet declared.

Example,

<html>
<head>
<title>Example/title>
<link rel="stylesheets" href="styles.css">
<link rel="stylesheet" href="https://mdn.com....">
</head>
</html>
Enter fullscreen mode Exit fullscreen mode

The browser will pick the last declared linked stylesheet because it has more specificity. In a case where the browser cannot read the latest linked stylesheet or doesn't support it, it falls back to the first one declared.

This also applies to your embedded <style> tag. If it comes before a <link>tag, the <link> tag will be picked first.

The further down your CSS rules are declared, the more specific they become. Your browser will always pick the last CSS rule declared.

An exception is your inline CSS. No matter the position of your inline CSS, it overrides all other CSS rules unless you give them an !important declaration.

Another scenario is where you apply the same rules to a specific element twice. You can declare the same properties with different values to a specific element but the last property and value will be applied.

Example,

h1{
   color:red:
   color:blue;
  }
Enter fullscreen mode Exit fullscreen mode

The result would be blue because it was the last rule to be declared and the most specific according to the browser.

You might wonder why a developer would declare two rules, the same properties but different values, for one element. They do this so the browser can have a fallback option if it can't read or doesn't support the second rule declared.

Second stage - Specificity

Think of this stage as a math test grade. Your class takes a test and everyone is scored with different grades, from the lowest to the highest. Now, imagine prizes are given based on how each student did on the test.

The highest scorer takes the biggest or highest prize and is seen as the most valued. Sure, other students are encouraged but the highest scorer takes the win.

Let's apply it to this stage.

Specificity is an algorithm that determines which CSS selectors are most specific through a scoring system to make those calculations.

You might be wondering, "What is a CSS selector?"

A CSS selector finds the HTML element(s) you want to style and applies the CSS rules you declare for it(them).

There are different categories of CSS selectors, namely five (5):

  1. Simple selectors: these select elements based on element name, id, and class.

  2. Combinator selectors: these select elements based on a specific relationship between them.

  3. Pseudo-class selectors: these select elements based on a certain state.

  4. Pseudo-elements selectors: these select and style a part of an element.

  5. Attribute selectors: these select elements based on an attribute or attribute value.

I'll be touching base on the simple and attribute selectors for this stage.

The simple selectors

As mentioned earlier, they select HTML elements based on the element name, id, or class.

Element name: h1, p, div, span, button, section, article, and a are examples of element names. The list goes on and on.
When styling with CSS, you pick any of the elements you want to style and give it a rule.

Example,

h1{
   font-size:20px;
   text-align:center; 
  }
Enter fullscreen mode Exit fullscreen mode
You're telling the browser that all <h1> elements in your HTML document should have a font size of 20px and should be center-aligned.

Class selector:This selector selects any element that has a specific class attribute.

To select elements with a specific class attribute, you put a period(.), followed by the class name you gave the element.

Example,

HTML

<p class="text">this is me</p>

Enter fullscreen mode Exit fullscreen mode
CSS

.text{ 
      color:pink;
     }
Enter fullscreen mode Exit fullscreen mode

You're telling the browser that any .text element should have the color "pink".

The class selector has a higher importance than the element name selector.

Id selector:This selector uses the id attribute of an HTML element to select a specific element. It is unique within a page. It has the most specificity. It is more important than any other selector and it overrides any other CSS rule you apply to the specific element if you have applied a CSS rule to the id attribute.

To select an element with a specific id, you write a hash (#) character, followed by the id of the element.

Example,

HTML 

<p id="style">style me</p>

Enter fullscreen mode Exit fullscreen mode
CSS

#style{
       background-color:black;
       color:white; 
      }
Enter fullscreen mode Exit fullscreen mode
You're telling the browser that #style element should have a background-color of black and a font color of white.

In summary, id > class > element name.

Universal selector

This selector selects all HTML elements to apply CSS rules.

Example,
*{
background-color:grey;
font-size:16px;
color:green;
}

You're telling the browser to apply these rules to all elements in your HTML page unless specified otherwise.

Attribute selectors

This selector targets elements with certain or specified attributes. It is usually denoted by two square brackets [].

Example,

HTML

<a href="twitter.com" target="blank">Twitter</a>

Enter fullscreen mode Exit fullscreen mode
CSS 

a[target] {
         Color:green;
        }
Enter fullscreen mode Exit fullscreen mode
You're telling the browser to make any a tag with the targetattribute have a font color of "green".

Why did I explain all these? To make you understand the importance of each selector and how they rank in CSS Specificity.

Back to specificity...

As mentioned earlier, specificity determines which elements are most specific through a scoring program. This is so because you can have the same element targeted with the same properties but different values. The one with the higher specificity wins.

Example,

<html>
<head>
  <style>
    .test {color: green;}
    p {color: red;}
   #hello {color:blue;} 
  </style>
</head>
<body>
<p class="test" id="hello">Hello World!</p>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

From explanations so far on simple selectors, which color do you think the browser would display?

Answer: if you chose "Green", you're on the right path.

If you chose "Red", I'll explain again.

In the example above, we told the browser to give the class selector, .test, a green color. We also told the browser to give the p element a red color. Lastly, we told the browser to give the #hello element a blue color. but the browser displayed a green text. Why? The id selector has higher importance than the class and name selectors.

Always remember: id > class > name

Another way to know which selectors are more important than the other is by calculating their specificity values.

Remember we mentioned it's calculated with a scoring program?

Start at 0, add 1 for each element selector or pseudo-element, add 10 for each class value, add 100 for each id value (or pseudo-class or attribute selector), and 1000 for inline styles.

Breakdown:

* Selector has a specificity value of 0

.test or [href] has a specificity value of 10

#style has a specificity value of 100

<p style="color:red;">two eggs</p> (inline CSS has a specificity value of 1000
Enter fullscreen mode Exit fullscreen mode

Remember that inline CSS overrides all other CSS rules unless they have an !important declaration. This is why it has a specificity value of 1000 and is the most important

So, the updated hierarchy would be: inline CSS > id > class > name

Example,

HTML

<p style="font-size:20px;" id="hello" class="text">hello there!</p>
Enter fullscreen mode Exit fullscreen mode
CSS

p {
   font-size:17px;
  }

#hello{
       font-size: 24px;
      }

.text{
      font-size:10px;
     }
Enter fullscreen mode Exit fullscreen mode

What font-size would the browser display?

Answer: 20px

Why, because inline CSS has more priority than any other selector in the stylesheet.

Now, if I add an !important declaration to one of the rules:

CSS

p {
   font-size:17px !important;
  }

#hello{
       font-size: 24px;
      }

.text{
      font-size:10px;
     }
Enter fullscreen mode Exit fullscreen mode

What font-size would the browser display?

Specificity calculation question:
What's the total score of this CSS rule?

  1. a.test#style -
  2. p[class] -

Answer:

  1. a.test#style - 111
  2. p[class] - 11
Note: it's always a good idea to keep your selectors simple when styling so you can easily style or overwrite with other CSS rules.

Third stage - Origin

The cascade takes into account the origin of the CSS because the CSS you write isn't the only CSS applied to a page.

If you've used Dev Tools, you must have noticed some CSS rules that were applied by default. Those are the browser's internal stylesheets or styles added by your browser's extensions or operating system.

The order of these origins from least specific to most specific:

  1. User agent base styles: these are default styles that your browser applies to HTML elements.

  2. Local user styles: these styles can come from your browser extensions that allow a user to write their own custom CSS for a webpage. They can also come from the operating system such as a default font size.

  3. Authored CSS: This is the CSS that you write or author. This has higher importance than the user agent stylesheet and the local user stylesheet. It overrides both. This is the CSS you link to your HTML page with a <link> tag or embed with a <style> tag in your head section or add to your HTML name elements (inline CSS).

  4. Authored !important: this is any !important declaration that you add to your authored CSS rule.

  5. Local user styles !important: this is any !important declaration that comes from the operating system or browser extensions.

  6. User agent !important: any !important that's defined in the default CSS provided by the browser.

Fourth stage - Importance

CSS rules are also applied based on their level of importance.

We'll be looking at the rank of importance from the least to the most important.

  1. Normal rule type - background, color, or border.

  2. animation rule type

  3. !important rule type

  4. Transition rule type

Animation rule type is more important than normal rule types because when an animation becomes active, its expected behavior changes its visual state and it overrides the normal rule type.

Same with transition rule types.

Summary

CSS (Cascading Style Sheets) is a language used to style HTML documents. There are three types of CSS: Inline, Internal, and External. Understanding how CSS rules are applied is crucial, and it involves understanding the CSS Cascade, which is the algorithm for solving conflicts where multiple CSS rules apply to an HTML element.

The CSS Cascade has four stages:

  1. Position and order of appearance: The order in which CSS rules appear matters. The browser will apply the last rule declared.
  2. Specificity: This determines which CSS selectors are most specific through a scoring system. ID selectors have higher importance than class and name selectors. Ultimately, inline styles have the most priority.
  3. Origin: The origin of the CSS matters, with authored CSS having higher importance than user agent and local user styles.
  4. Importance: CSS rules are applied based on their level of importance, with animation and transition taking more priority because of the changes in visual state/behavior.

Understanding these stages helps resolve conflicts and ensures that CSS rules are applied as intended.

I hope you find this post useful when you face problems relating to CSS.

Thanks for reading! Share your thoughts in the comments below.

Learn, code, repeat!

Top comments (0)