DEV Community

Kushal
Kushal

Posted on

[2] Specificity and Cascading in CSS

Cascading and Specificity in CSS ☕

It's second post in #CSSForDevelopers series. The purpose of calling this #CSSForDevelopers is because developers sometime have tough time to connect with CSS. but #CSS is also an important aspect if you are moving towards full stack development or architecture an application.

In #CSSForDevelopers series, I will be posting the CSS concepts from basics of CSS to styling a #react component.

What is Cascading. So, what is the problem that we are trying to solve?

Here we have a stylesheet where we may have different styles defined for the same element.

Look at this example, where we are trying to give color to body as well as to the div. The div is inside body. So, now what will be the background-color of Div? What will happen when you don't have background-color set specially for div? These are some of the open questions that we will be answering in this post.

⚠️ The sample HTML that we will be using is at this GIST Link: You can copy the code from here on paste to any online editor like repl.it

TRY IT YOURSELF 1

CSS Code:
div  p {
    background-color:  #ffff00; // yellow
}

p {
    background-color:  #ff0000; // red
}

p.abc-myclass {
    background-color:  orange; // orange
}
Enter fullscreen mode Exit fullscreen mode
HTML Code:
<body>
    <h1>This is h1 directly under body</h1>
    <p  class="abc-myclass"> Test class attribute para </p>

    <div>
        <h2>I am h2 directly under div</h2>
        <p  data-test="001">This is para inside div, but not directly inside div</p>
    </div>

    <div>
        <p  class="abc-myclass">This is para directly inside div</p>
        <span>
            <p>This is para inside span</p>
        </span>
    </div>

    <p  class="myclass"  data-test="001">I am paragraph directly inside the body and below a div</p>
    <a  href="github.com/kushalseth"  target="_blank">GIT rofile</p>
</body>
Enter fullscreen mode Exit fullscreen mode

Expected Output:

Output

This is the problem that we are going to talk about in this post. Stay with me for sometime.

Note: If you know the very basics, you can directly jump to below heading: "PART-2: Different style is applied through multiple resources on the same element.". That has information on how specificity works.

Understanding Cascade

Styles can come from multiple sources, so we need to understand which style will be applied to the element.

Wondering, How you will have multiple styles? This is because, we may have

  • Author stylesheets (inline- css or third party style sheets), These are the style sheets that we load in our application. It could be our application's stylesheet or some third party stylesheet that gets loaded when we include third parties.

  • User stylesheets, Behavior that can be added to any web page when opened in your browser. Each browser has settings to set the style based on user preference to all the pages that we open. You can update that as well. Suppose you want font to be bold for all the webpages that you open in a browser, you can do that from the settings of browser. These kind of style sheets are called User Stylesheets.

  • Browser default style sheets (user agent style sheets): Each browser has some pre-defined CSS for the elements known as user agent stylesheets. Each browser has it's own way of handling the default styles for the tags. Few developers prefer to reset the default stylesheets to have a more control over the application across the browsers. They define default styles for all the elements in a CSS.

🔺 So, our First rule is:

The Order of preference if all three are applied on the same element is: (The style with more weight will be applied)

-> Least weight to Most weight
-> Browser default style sheets -> User stylesheets -> Author stylesheets

So, suppose we have browser default style sheet as well as User Stylesheet on the element, then userstylesheet will be preferred, and you can see the style mentioned in userstylesheet.

In the same way, if you browser default style sheet as well as author defined style sheet, then author defined style sheet will be applied to the element. But if you use !important in user stylesheet for any style then that would be preferred over author stylesheets,

Now, in next heading, let's discuss how, cascading would work when we have multiple author based stylesheets.

Rules for Author defined style sheets:

PART-I: Same style is applied through multiple resources on the same element.

Now, we know, author defined cascading rules have highest priority. What will happen in the scenarios where our pages can have similar styles for the same element.

Suppose, within a style sheet we have something like this:

div { background-color: #ff0000; } // red
div { background-color: #ffff00; } // yellow
Enter fullscreen mode Exit fullscreen mode

or in two different files we have something like this:

stylesheet1.css Code:
div { background-color: #ff0000; } // red

stylesheet2.css Code:
div { background-color: #ffff00; } // yellow
Enter fullscreen mode Exit fullscreen mode
HTML Code:
<head>
<title>CSS for Developers</title>
    <link rel="stylesheet" href="stylesheet1.css" type="text/css"  />
    <link rel="stylesheet" href="stylesheet2.css" type="text/css"  />
</head>
Enter fullscreen mode Exit fullscreen mode

DID YOU TRIED!!

In above shown example, both the times, the style with background-color: #ffff00 wins.

🔺 So, our Second rule is:

⚠️ This rule is very specific to element when we have exact same style rule coming from different sources. Like the example, we have taken: Be very careful here! Next we will check Specificity, that will handle those scenarios in which we don't have same rule on the element.

-> Whatever be the last style, it will win. 
So, in both the scenarios, background-color: #ffff00 will load 

The example with which we have started will need some more knowledge of rules. So, let's start with Specificity

Rules for Author defined style sheets:

PART-2: Different style is applied through multiple resources on the same element. Specificity

Great! till now, we have learned two cascading rules. Now, let's dive deeper.

In last rule that we have learned, we have identified that if the same styles are applied to an element from multiple sources, we prefer the one which loads at the last.

But what will happen when styles are different on the same element? Like the scenario, we have have picked in start. (please refer: TRY IT YOURSELF 1)

If we observe, there are three different styles,

  • One style says, apply yellow color to all those "p" tags which are inside div tag.
  • One style says, apply red to all the "p" tags.
  • Third style says, apply orange to all the divs which has class abc-myclass.

⚠️ How does this work, it will not follow rule 2, as we have different styles on the same element. The browser provides some specificity degree to all the styles and then applies that has highest specificity. We can think of specificity as degree of weightage.

Specificity is more of logical unit of how specific our styles are for some particular element. I would suggest you to read both logical and Theoretical concepts and understand logically instead of learning any formulas or tricks.

Logical Explanation

Let's pick each of the three rules.

  • The style with classname (p.abc-myclass) is most specific to the element. It refer to only those p tags which has abc-myclass class.
  • The style with just p tag is generalized and applies to all the p tags. and
  • Same is the case with under tag style. (div p) style is more specific then normal "p" tag but less specific then (p.abc-myclass) style.
-> So, we just have to observe which style is {MOST} specific to an element. 
 In our case, p.abc-myclass is most specific to the element.

This is a high level understanding of how specific the css rule is. let's dive more deeper.

Theoretical Explanation

Specificity is more of logical unit. How specific our styles are for some particular element.

Let's consider it as a weightage that we will give to our styles for that element. This weightage is a number which has 3 digits.

This weight could be anything like: 100, 010, 001 etc. So, we can consider them as three digit number that can be represented as ABC.

Now, how we will give this weight to our styles. To give weight to our styles. Let's see how each digit of the weight is defined.

As discussed, weights could be 100. 010, etc. So, we can define it as ABC. Any number can be divided into ones, tens and hundreds place values. Let's see, which type of selector(selectors like: class, id, element or type selectors), fall in each category.

If you just want to revise your concept of types of selectors or pseudo-class, please refer selectors section of this article: (Types of CSS selectors)

  • C (unit place of number): So the unit digit of the weight can be given to count of type selectors and universal selectors.

I am adding universal selectors here because they have no impact on Specificity.

So, if we have css something like these then there specificity would impact the unit place of number.

   div { color: red } // Specificity: 001 (1 div element)
   * { color: yellow } // Specificity: 000 (1 universal selector)
   li { color: yellow } // Specificity: 001 (1 li element)
   div, p { color: yellow } // Specificity: 001 (all li and div element. since this is similar to applying color to individual element) If you get confused, just forget this example as of now. 
   div p { color: yellow } // Specificity: 002  (p tags inside div tag, 2 tags considered )
Enter fullscreen mode Exit fullscreen mode
  • B (tens place of number): Tens place can be given to count of class and attribute selectors.
   .nav { color: red } // Specificity: 010 (1 class)
   [title] { color: yellow } // Specificity: 010 (1 attribute) 
Enter fullscreen mode Exit fullscreen mode

Let's see some examples of BC combined:

   li.nav { color: red } // Specificity: 011 (1 element, 1 class)
   a:hover { color: yellow } // Specificity: 011 (1 element, 1 pseudo-class)
   a[title] { color: yellow } // Specificity: 011 (1 element, 1 attribute) 
Enter fullscreen mode Exit fullscreen mode
  • A (hundreds place of number): Hundreds place can be given to count of id selectors.
   #nav { color: red } // Specificity: 100 (1 id)
Enter fullscreen mode Exit fullscreen mode

Combined examples of ABC

   #nav li.myclass { color: yellow } // Specificity: 111 (1 id, 1 class, 1 element) 
Enter fullscreen mode Exit fullscreen mode

Exceptions in Specificity (Extending ABC to YZABC):

The ABC rule holds good in all the scenarios. except inline and !important styles.

  • Z (Thousands place of number): inline styles: It will be at higher priority then above ABC rule, So, if there is any inline style then the specificity will be: 01000
  style="color:blue;" // Specificity: 01000
Enter fullscreen mode Exit fullscreen mode
  • Y (Ten thousands place of number): when you have important in any style sheet:
  a { color: blue !important } // Specificity: 10000
Enter fullscreen mode Exit fullscreen mode

I guess, after analyzing so many examples, we have some basic understanding of what is specificity. There is a lovely graphical representation by @estellevw for specificity: graphical representation for specificity

Let's check specificity in our example:

div  p { background-color:  #ffff00; // yellow } // Specificity: 002 (2 elements)

p { background-color:  #ff0000; // red } // Specificity: 001 (1 elements)

p.abc-myclass { background-color:  orange; } // Specificity: 011 (1 class, 1 elements)
Enter fullscreen mode Exit fullscreen mode

🔺 So, our Third rule is:

⚠️ Remember, higher the specificity, that style will be applied to the element.

Inheritance

If we check our HTML code, then each element is inherited from the parent element. In our example, p tag is child of div and another p tag is child of body. So, basically, all the elements holds a child-parent relationship in DOM (Document object model).

There are some properties that we can set in parent that can be inherited to the child.

⚠️ The sample HTML that we will be using is at this GIST Link: You can copy the code from here on paste to any online editor like repl.it

<body>
    <div>
        <h2>I am h2 directly under div</h2>
        <p  data-test="001">This is para inside div, but not directly inside div</p>
    </div>
    <p  class="myclass"  data-test="001">I am paragraph directly inside the body and below a div</p>
</body>
Enter fullscreen mode Exit fullscreen mode
div {
   background-color:  #ffff00; // yellow
}
Enter fullscreen mode Exit fullscreen mode

The above code will make this section as yellow: So, p has inherited the back-ground-color property of div tag.

// This section will be yellow 
<div>
    <h2>I am h2 directly under div</h2>
    <p  data-test="001">This is para inside div, but not directly inside div</p>
</div>
Enter fullscreen mode Exit fullscreen mode

We can override the inherited values by applying explicit css to the inherited element. Something like this:

div {
   background-color:  #ffff00; // yellow
}

p {
   background-color:  #ff0000; // red
}
Enter fullscreen mode Exit fullscreen mode

Output this time:

Output

What's Next

It's too much information in this part-2. Let's start fresh in next part-3 about CSS Box Model.

Where we will check how margins, borders and padding works for DOM.

Stay Connected and Stay Save.

Oldest comments (0)