Basic CSS: Cascading, Specificity, and Inheritance in CSS

Lesson 6: Cascading, Specificity, and Inheritance in CSS

/en/basic-css/colors-in-css/content/

Cascading, Specificity, and Inheritance in CSS

Imagine you're working on the CSS stylesheet for a webpage, and you decide to make all the links have purple text. You add a CSS ruleset to do it and it looks great. Then you take a break, but when you come back, you forget about the change you made, so you add an additional ruleset that changes links to have green text. You've now told your browser to do two conflicting things, so what should it do?

As you add more and more CSS to a stylesheet, you will inevitably run into conflicts like that. Fortunately, three fundamental concepts can help you understand how a browser decides what to do in such situations: cascading, specificity, and inheritance.

Cascading

waterfall cascading over rocks, with CSS selectors in water

Cascading refers to the logic your browser uses to determine which CSS rulesets are the most important, especially when they conflict with each other. One of the simplest ways your browser does this is by paying attention to the order in which your rulesets appear. In short, if you create multiple rulesets with the same selectors and declarations, the last one in your stylesheet will be the most important to your browser

For example, imagine your stylesheet looked like this:

a {
  color: purple;
}
a {
  color: green;
}

Both rulesets are targeting the same HTML—all <a> elements on the page—but telling the browser to do two different things, and it can't do both at once. By cascading, your browser is able to choose which of the rulesets to follow. Think of it like water cascading over rocks in a stream: your browser will flow over and consider each of the rulesets in the stylesheet, but it won't definitively settle on any until reaches the end.

In the case of this example, that's the ruleset with the color: green; declaration, because it comes last in the stylesheet. The browser would consider the color: purple; ruleset as it flows over it, but ultimately settle on the one that comes later.

Keep in mind that the order in which you add things to your stylesheet only matters when it comes to resolving those sorts of conflicts. If your rulesets don't conflict at all, you can put them in whatever order you want.

Specificity

computer screen with 3 HTML paragraphs, and one paragraph has an ID of "special"

Another common conflict with CSS rulesets is when you have multiple rulesets with different selectors targeting the same elements. For example, imagine you added a few paragraphs to your webpage, but gave just one of them an id attribute:

<p>Just some paragraph</p>
<p id="special">One with an id</p>
<p>Just another paragraph</p>

Then imagine that you added a couple of CSS rulesets. One of them targets paragraphs in general, while the other targets the id you added:

#special {
  color: green;
}
p {
  color: purple;
}

Because the p selector targets all <p> elements on the page, and the element you added the "special" id to is a <p> element, you've told your browser to do two conflicting things. Like before, it can't do both things at once. However, your browser uses the concept of specificity to determine which ruleset to follow, and it cares even more about specificity than it does about the order. 

That means that the browser will choose whichever ruleset has most specific selector, regardless of how the rulesets are ordered. In the example above, the text would be green, because the #special selector is more specific than the p selector.

CSS selectors follow a consistent hierarchy when it comes to specificity, so you can always tell which selector is the most specific. For example:

  • Elements: If your selector is an HTML element, like p, it's not very specific. It applies broadly to every <p> element on the page.
  • Classes: If your selector is a class, like .specialParagraphs, it's more specific. It could apply to more than one element, but only the ones where you've added that particular class.
  • Ids: If your selector is an id, like #uniqueParagraph, it's very specific. A webpage should only include any given id once, so it should always be pointing to just one HTML element.

There are a number of other more advanced ways to increase the specificity of your selectors, most involving multiple selectors separated by spaces or symbols. We won't be focusing on them in these lessons, though. 

Inheritance

father and son with similar physical appearance

While cascading and specificity are explicitly about resolving conflicts, inheritance is more about keeping your CSS orderly and avoiding unnecessary repetition. In other words, understanding inheritance will help you avoid conflicts in the first place.

Imagine you have a <div> element with a <p> element inside of it:

<div>
  <p>Here's a paragraph</p>
</div>

Any time an HTML element contains another element, they are commonly described as a parent and a child. In this scenario, for example, the <div> element would be called the parent, while the <p> element would be the child. And just like in human relationships, the parent often passes down traits to its child.

For example, let's say you changed the font of the <div> element:

div {
  font-family: 'courier';
}

Despite the fact that you targeted only the <div> element, the text in the <p> element would still be displayed with the new font. That's because the <p> element inherits the font-family declaration from its parent, the <div> element. 

The same principle applies even many levels up. For example, if you were to change the font of the <body> element—and if you've been following along with the do-it-yourself project, you've already done this—it would be passed down to all of its children. Because the <body> element contains all of the other visible HTML elements on the page, they would all inherit the font that you gave to it.

Non-inheritance

While many CSS declarations are passed down from parent to child, not all of them are. For example, consider the <div> example above. Let's give it some background colors for visibility, plus a height value for the <div> element:

p {
  background-color: khaki;
}
div {
  background-color: lightblue;
  height: 200px;
}

If you were to load that in the browser, you'd see something like this:

Div and paragraph with height

Most of what you see is the blue area—the <div> element—because it has a height value, and height is one of the CSS declarations that isn't inherited. If the p element had inherited that height value, you wouldn't see any blue at all.

As with many elements of CSS, remembering which elements inherit and which don't is mostly a matter of experience. What's important is understanding the broad concepts so that you have an idea of what to look up when you aren't sure how to do something.

/en/basic-css/organization-and-sizing-in-css/content/