CSS3 Tutorial: the cascade sequence

The cascade sequence

As an experienced web designer, you have probably ever experienced the situation where you wanted to apply a style rule to an element, which seemed to be having no effect, no matter what you tried. To illustrate this see example 1 where I try to overwrite the first rule #precedence{color:red;} in order to get a green color for the text instaed of red. In the example it doesn't succeed however and that's because ID selectors (#precedence in our example) have a higher priority than class selectors (.precedence) have a higher priority than element selectors (p and h3).

Example1: can't get the text green. It stays red *@!&#^*!! Why?

<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Priority in CSS stylesheets</title>
</head>
<style>
   #precedence{
   color:red;
   }
   .precedence{
   color:red;
   }
   /* I want to override the above rules now,
but without succes, the title and text remain red */ h3{ color:green; } p{ text-align:left; color:green; } </style> <body> <h3 id="precedence">A common mistake</h3> <p class="precedence">A common mistake is to think that style rules that are physically present earlier in the stylesheet take precedence over later style rules.
That is incorrect. The order of application of style rules is determined by the priority granted by the browser.</p> </body> </html>

Image 1. Can't get the text green! It stays red!

Check this example in your browser

When I change the style rules as follows, it finally works: the text is green now!


<style>
   #precedence{
   color:red;
   }
   .precedence{
   color:red;
   }
   /* I want to override the above rules now, 
   this time with succes, the title and text are green*/
   h3.#precedence{
   color:green;
   }
   p.precedence{
text-align:left;
   color:green;
   }
</style>


Image 1a. Now it's green!

Check this example in your browser

Style Rules in Cascading Style Sheets (CSS) are applied in a predefined order of priority (and NOT in the order of occurrence). This is the meaning of the term cascading in Cascading Style Sheets (CSS). Style Sheets and style rules are therefore always in competition with each other regarding the order of application.

CSS allow the application of multiple style rules to the same element and they use the cascading sequence to determine which style rule has priority. The cascade sequence divides style rules into 6 groups based on the type selector which is being used in the style rule. A line in a higher priority group overrides a competing line in a group of a lower priority. Groups are ranked according to the degree of specificity of selectors. Selectors in groups with low priority have a lesser degree of specificity compared to selectors in groups with a higher priority. The guiding principle is that generic selectors apply generally applicable styles, and that specific selectors override the generic selectors. Let's take a look at the order of priority of the six different groups of style rules:

  1. The group with the highest priority has rules containing ‘!Important’. These will override any non-! Important rules. For example, #abc {margin: 6px! important;} overrides #xyz {margin: 12px;}.
  2. The group with the priority 2 contains rules in the style attribute placed in the page.
  3. The group with the priority 3 contains rules with one or more ID selectors such as # abc {margin: 6px;} and overrides * .efg {margin: 12px;}..
  4. The group with the priority 4 contains rules with one or more classes, attributes, or pseudo selectors, for example, *.abc {margin: 6px;} takes priority over div{margin: 12px;}.. }.
  5. The group with the priority 5 contains rules with one or more elementselectors, for example div {margin: 6px;} takes priority over *{margin: 12px;}.
  6. The group with the lowest priority contains rules with a universal selector, for example, * {border: 1px solid red;}.

When style rules are located in groups with equal priority and contain equal number of selectors with the same priority, then subsequently the priority order based on location applies:

  1. CSS declarations in the user style sheet, marked as important! have the highest priority.
  2. The location with priority 2 is the <style> element in the head of the HTML document. For example, a rule in <style> overrides a rule in a style sheet that is imported by an @ import statement places within<style>.
  3. The location with priority 3 is a stylesheet imported by an @ import statement placed within the <style> element.
  4. The location with priority 4 is a stylesheet placed by the <link> element.
  5. The location with priority 5 is a stylesheet imported by an @ import statement and placed in a stylesheet that is loaded by a <link> element.
  6. The location with priority 6 is the user stylesheet (except the lines with important! See pt.1).
  7. The user agent stylesheet has the lowest priority.

When multiple style sheets are imported or placed on the same location, then the priority is determined by the order of placement. The later placed, the higher the priority.
When competing rules in an equal selector group with the same number and priority of the selectors, and similar location, the precedence goes to rules issued later.

 

Calculating the specificity of a rule

The specificity of a selector can be calculated which results in a numeric value. This is how: the specificity is broken down into four components: a, b, c and d. a has the highest specificity, d has the lowest

  • for an inline style; a=1;
  • b= the total number of ID selectors;
  • c= the number of class, pseudo-class, and attribute selectors;
  • d= the number of type selectors and pseudo-element selectors;

Now we can calculate the specificiy of any CSS selector by using the following table. a has the highest specificity, d has the lowest. The higher the number for the specificiy in Base 10,the higher the specificiy

Specificity of CSS selectors
Selectorspecificiyspecificiy in Base 10
Style="" 1,0,;,01000
#container #mainContent{}0,2,0,0200
#wrapper .article{}0,1,1,0110
section#part1{}0,1,0,1101
#part1{}0,1,0,0100
div.books .dateissued{}0,0,2,121
div.books{}0,0,1,111
div h2{}0,0,0,22
p{}0,0,0,11
   

In the example below a stylesheet is applied to a division (<div>) element. Each rule refers to a different border-width of the <div>.

The styles in the style sheet are arranged in cascading order from lowest to highest priority.
As you can see, the browser applies the final rule to the <div> and places a 14px border around the div. The browser applies this rule because it has the highest priority in the cascade sequence: an ID selector with !important.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
</head>
<style>
   html, body { border-style: none !important; }
   * { border: 0px  solid orange; }                /* Universal Selector */
   div { border: 2px solid brown; } /* Element Selector */
   * .me3 { border: 4px solid yellow; } /* Secondary Selector */
   #me2 { border: 6px solid black; } /* ID Selector */
   * { border: 8px  solid violet !important; } /* ! Universal Selector */
   div { border: 10px solid blue !important; } /* ! Element Selector */
   * .me3 { border: 12px solid green !important; } /* ! Secondary Selector */
   #me2 { border: 14px solid red !important; } /* ! ID Selector */
   </style>
<body>
<div id="me2" class="me3"> !important has the highest  priority. </div>
</body>
</html>

A recommendation regarding the design of your stylesheets which we can do on the basis of the above information is: sort the CSS rules in your stylesheet using the cascade sequence. Sorting rules in this way, makes it easy to keep track of the way in which competitive rules are applied and what rules overwrite each other. As an example, the following sorting can be employed:

/* Universal Selectors */
/* Element Selectors */
/* Class, Attribute, and Pseudo Selectors */
/* ID Selectors */
/* ! important Universal Selectors */
/* ! important Element Selectors */
/* ! important Class, Attribute, and Pseudo Selectors */
/* ! important ID Selectors *

Conclusion

The search for 'failing' style rules in stylesheets can be accompanied by a lot of wasted time and frustration. The understanding of the cascade sequence and, based on that, structuring the division of your stylesheets makes that you will save a lot of time because you do not have to search for the reason why your style rules do not work, especially if you're using multiple stylesheets.

Leave a comment