Back

Understanding CSS Cascade

Understanding CSS Cascade

CSS is called a cascading stylesheet, and that is because of how the browser renders styles that apply to our elements. Unfortunately, CSS is complicated, and your browser often finds itself resolving conflicting CSS rules; it uses an algorithm called the Cascade. The CSS cascade is one of the most popular parts of CSS. This article will explain the CSS cascade, its importance, and the algorithm.

What is CSS Cascade?

Our webpages are styled using CSS, which stands for Cascading Style Sheets. The Cascade is an algorithm specifying how user agents integrate property values from several sources. When more than one style rule applies to a specific element on a web page, the browser determines which rule to apply by using a cascade. It decides how the rules are applied in what sequence and what occurs when two rules for the same element conflict. It refers to the sequence in which a property is applied to an HTML element.

Importance of CSS Cascade

The CSS cascade is an essential concept in web development because;

  • It determines the sequence in which CSS styles are applied to an HTML element.

  • It is essential to ensure your styles are applied reliably and consistently across various browsers and devices.

  • It enables you to define styles hierarchically, with more specific styles set further down the hierarchy than more general styles. This makes it easier to maintain your styles and make global changes to your website or application.

  • Additionally, you can apply your custom styles to particular elements or collections using the CSS cascade to override the default styles. This can help create aesthetically beautiful and virtually consistent websites and applications.

  • The CSS cascade is important in web development because it provides a way to apply styles consistently and maintain web pages and applications.

The Cascade algorithm

The following steps apply to the cascading algorithm:

  • Order
  • !Importance
  • Specificity
  • Origin

Let’s take a look at the different cascade algorithms.

Order

In the cascading style sheets (CSS) model, the “source order” refers to the order in which style rules appear in the CSS file. If two rules have the same specificity and neither is marked as !important, the rule that appears later in the CSS file will take precedence.

For example, consider the following CSS:

    h1 {
      color: red;
    }
    
    h1 {
      color: blue;
    }

In this case, both rules apply to h1 elements and have the same specificity, so the rule that appears later in the CSS file (color: blue;) will take precedence. The h1 elements will be rendered with a blue color.

It’s important to be mindful of the source order when writing CSS, as it can affect how styles are applied to elements on the page. It’s generally a good idea to put more specific rules earlier in the CSS file so that they can be overridden by more general rules if necessary.

!Importance

The importance of a style rule is determined by the presence of the !important directive. A style marked as !important will always be applied, regardless of the rule’s specificity or the order in which it appears in the stylesheet.

For example:

    p {
      color: red;
    }
    
    p {
      color: blue !important;
    }

In this example, the second rule will be applied to all paragraphs on the page, resulting in blue text. This is because the !important directive takes precedence over the first rule, even though it has the same specificity.

Specificity

Specificity in CSS is the algorithm used by browsers to choose the most appropriate CSS declaration for an element. This algorithm also chooses the appropriate property value to apply to the element. After establishing the Cascade’s origin and importance, browsers take specificity into account.

Specificity rules include;

  • The CSS styles you apply by referencing an external style sheet have the lowest priority and are overridden by internal and inline CSS.
  • Internal CSS is overridden by inline CSS
  • Inline CSS has the highest priority and overrides all other selectors.

Specificity Hierarchy

Specificity hierarchy is the order in which style rules are applied to an element; the rule with the highest specificity takes precedence.

Here’s the specificity hierarchy from the highest to the lowest:

  1. Inline styles: An inline style is applied to an element directly using the style attribute in the HTML. An inline style has the highest specificity, as it is directly applied to the element.
  2. IDs: An ID selector has a higher specificity than a class selector. For example, the following rule will be applied to an element with an ID of “main”: #main { }
  3. Classes, attributes, and pseudo-classes: These selectors have a lower specificity than an ID selector, but a higher specificity than an element selector. For example, the following rule will be applied to any element with a class of “highlight”: .highlight { }
  4. Elements and pseudo-elements: These selectors have the lowest specificity. For example, the following rule will be applied to all p elements: p { }

Here are some examples to illustrate the concept of specificity:

    h1 {
      color: blue;
    }
    
    .my-class {
      color: green;
    }
    
    #my-id {
      color: red;
    }

    <h1 class="my-class" id="my-id">Hello World</h1>

In this example, the text color of the h1 element will be red because the ID selector has the highest specificity and overrides the other two declarations.

Example 2:

    h1 {
      color: blue;
    }
    
    .my-class {
      color: green;
    }
    
    #my-id {
      color: red;
    }
    
    h1.my-class#my-id {
      color: yellow;
    }
    
    <h1 class="my-class" id="my-id">Hello World</h1>

In this example, the text color of the h1 element will be yellow because the last declaration combines three selectors of different types (type, class, and ID), resulting in a higher specificity than any other declarations.

How to calculate specificity

To calculate the specificity of a selector, you can follow these steps:

  1. Assign a value of 1 to each element (type) selector and 0 to each class, attribute, and pseudo-class selector.
  2. Assign a value of 1 to each pseudo-element selector and 0 to each class, attribute, and pseudo-class selector.
  3. Assign a value of 1 to each ID selector and 0 to each attribute and pseudo-class selector.
  4. Add the values for each selector in the compound selector.

For example

    #header p.intro em[title^="Hello"]::before

To calculate the specificity of this selector, you would do the following:

  • The element selector p has a value of 1.
  • The class selector .intro has a value of 1.
  • The attribute selector [title^= "Hello"] has a value of 1.
  • The pseudo-element selector ::before has a value of 1.
  • The ID selector #header has a value of 100.

Adding these values together, the specificity of the selector is 103.

Remember that specificity only comes into play when there are conflicting declarations. If there are no conflicting declarations, then the last declared style will be applied to the element.

Session Replay for Developers

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — an open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

Origin

The origin of a style rule is one of the factors that determines its priority in the Cascade. In general, author styles have the highest priority, followed by user styles, and finally user agent styles. For example:

    /* Author style */
    p {
      color: red;
    }
    
    /* User style */
    p {
      color: blue !important;
    }
    
    /* User agent style */
    p {
      color: green;
    }

In this example, the second rule (the user style) will be applied to all paragraphs on the page, resulting in blue text color. This is because the user style has higher priority than the other two styles due to the !important directive. Another example:

    /* Author style */
    p {
      color: red;
    }
    
    /* User agent style */
    p {
      color: green;
    }
    
    /* User style */
    p {
      color: blue !important;
    }

In this example, the third rule (the user style) will also be applied to all paragraphs on the page, resulting in the blue text color. This is because the user style has higher priority than the other two styles due to the !important directive, even though it appears after the other two styles in the stylesheet.

Types of Origin

  • User agent styles: User agents have fundamental style sheets that apply default styles to any document. These style sheets are known as user-agent style sheets. They are the default styles that your browser applies to HTML elements. Typically, they are based on a set of design guidelines.

  • Local user style: Local user style is a set of CSS guidelines applied to a particular website or web application by the browser user as opposed to the website’s creator. These styles can alter a website’s behavior or appearance to suit the user’s preferences. Local user styles are frequently saved in the browser’s local storage and are only used with the particular websites or web applications for which they were designed.

  • Authored CSS: Authored style sheets are the most common type of style sheets. These styles reset user-agent styles and specify the styles for a specific web page or application’s appearance. CSS that has been created is often kept in separate files called “style sheets” that are connected to the website’s HTML files. The developer can control the look and feel of a website by applying the styles in these style sheets to the HTML elements in the website.

What is Inheritance in the CSS Cascade?

In the CSS cascade, the term “inheritance” refers to an element’s capacity to take on the values of some of its ancestors’ properties. Accordingly, if an ancestor element contains a value for a property, that value will be transferred to its descendant elements unless a more precise or higher priority value is supplied for the descendant (child) element.

Here’s how inheritance works in CSS cascade:

For example, consider the following HTML structure:

    <div class="container">
      <p>Some text</p>
    </div>

If we set the font-size property for the div element in our CSS like this:

    .container {
      font-size: 16px;
    }

The p element will automatically inherit the font-size: 16px value from the div element unless we specify a different value for the p element. For example:

    p {
      font-size: 24px;
    }

In this case, the p element will have a font-size of 24px because the value specified for the p element is more specific and has a higher priority than the inherited value from the div element.

It’s important to note that not all properties in CSS are inherited. Properties such as [border](https://developer.mozilla.org/en-US/docs/Web/CSS/border-style), [padding](https://developer.mozilla.org/en-US/docs/Web/CSS/padding), and [margin](https://developer.mozilla.org/en-US/docs/Web/CSS/margin) are not inherited by default, so if you want to apply these properties to an element, you will need to specify a value for them directly on the element.

Inheritance is a useful tool in CSS that allows elements to inherit values for certain properties from their ancestors. This can save time and effort when styling a website, as you don’t have to specify a value for every property for each element in the document.

Common pitfalls to avoid when using the CSS Cascade

Here are some common pitfalls to avoid when using the CSS cascade:

It’s essential to understand the order in which styles are applied in the CSS cascade, as this can affect the final value of a property for an element. The Cascade works by considering the styles specified in the following order: browser default styles, user agent styles, author styles, and user styles.

If you don’t specify a value for every property for an element, the element will inherit values for those properties from its ancestors. This can lead to unexpected results, especially if you are not aware of the values that are being inherited.

When you want to override a style that has been applied to an element, it’s important to use a selector with higher specificity. A selector with lower specificity may not override the original style, even if it appears later in the stylesheet.

The !important rule can be used to prioritize a style, but it should be used sparingly, as it can make your stylesheets more challenging to maintain. Overusing the !important rule can also lead to conflicts and inconsistencies in your styles.

The inheritance chain determines the order in which styles are applied to an element, starting with the element itself and working its way up through its ancestors. It’s important to consider the inheritance chain when styling an element, as it can affect the final value of a property for the element.

By avoiding these pitfalls, you can effectively use the CSS cascade to style your website and create the look you desire.

Conclusion

The CSS cascade is an essential component of web development because it enables programmers to design complex and flexible style sheets that can be used in various situations. It is also important in the process of debugging and resolving CSS problems. Knowing the Cascade will enable you to determine which rules are being applied and why.

A TIP FROM THE EDITOR: For more on CSS, don’t miss A Complete Guide To CSS Fundamentals.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs and track user frustrations. Get complete visibility into your frontend with OpenReplay, the most advanced open-source session replay tool for developers.

OpenReplay