Register to get access to 15+ free programming courses with interactive exercises

CSS Cascading Modern layout fundamentals

In the last lesson, we dealt with the second part of the phrase Cascading Style Sheets, namely style sheets. We have studied how styles are written and applied to various HTML elements. In this lesson, we'll talk about the meaning of the word cascading.

What is cascading? Imagine a cascade of waterfalls. In them, the water flows from one waterfall into another and so on until it all goes into a single common pool.

CSS cascading

In CSS, the word "cascading" has the same meaning. CSS properties are our water. They can overlap and overlay each other. In other words, cascading is the ability of CSS to overlay properties on top of each other, as well as to extend properties in selectors.

Perhaps this description seems rather complicated; let's look at an example. Create a paragraph with two classes: text-bold and text-dark. The first class will be responsible for bold text, and the second for making the font darker. Let's also add a tag selector and set the font size to 24 pixels.

<p class="text-bold text-dark">Some very interesting text about an interesting thing. Very interesting.</p>

In the CSS file, we'll give the following styles:

p {
  font-size: 24px;
}

.text-bold {
  font-weight: bold;
}

.text-dark {
  color: #333333;
}

Try this example, and you'll see that the text is displayed with a dark color and is bold. Styles from the text-bold and text-dark classes have been applied to our paragraph. Additionally, the text size has been set to 24 pixels, the value we specified for the tag selector.

The final styles for our paragraph will be:

{
  font-size: 24px;
  font-weight: bold;
  color: #333333;
}

This is the cascading part of Cascading Style Sheets. Although we used different selectors and classes to describe them, in the end, they were consolidated.

Selector precedence

An important feature of CSS is that different types of selectors have different priorities. If styles in different selectors contradict each other, the precedence principle comes into play. Let's look at an example. Take the paragraph with the class red and the identifier blue. Set the appropriate colors for the text. However, let's set the color for all the paragraphs in the text to green.

p {
  color: green;
}

.red {
  color: red;
}

#blue {
  color: blue;
}
<p id="blue" class="red">What color will the paragraph be?</p>

Before you read on, try performing this example wherever you're comfortable.

As you may have noticed, the text of the paragraph will be blue. But why? Could it be that blue is the last color specified in the CSS? In this case, no. Even if we move the ID selector to the very top, the paragraph will still be blue.

The point is that the ID selector has the highest priority. When it comes across it, the browser will consider these styles the most important for the page and in case of contradiction will take the value from the styles for the ID first.

The selectors can generally be arranged in the following order of precedence:

  1. ID selector #blue
  2. Class selector .red
  3. Tag selector p

Where 1 is the highest priority and 3 is the lowest.

Selector precedence

Let's look at another example:

p {
  color: blue;
  font-weight: bold;
}

.important {
  color: purple;
  font-style: italic;
}

#intro {
  color: green;
}
<p class="important" id="intro">The Manahatta and Canarsee Native American tribes</p>

This text will be italic, bold, and green. And here's why:

  • Tag selector p:
    • Adds blue color
    • Adds boldness
  • Class selector .important:
    • Replaces blue with purple
    • Makes text italicized
  • ID selector #intro:
    • Replaces purple with green

After all these changes we've made, the final styles for the paragraph will be as follows:

{
  color: green;
  font-weight: bold;
  font-style: italic;
}

Note: since the identifier selector has the highest priority and overrides all class styles, it's considered bad practice to use it. By specifying styles for the identifier, we take away our ability to override the styles using classes. This is very important when creating sites that respond to the user's actions, i.e., if we change the appearance when the user does something.

Redefining properties

You may be wondering what happens if an element has several classes whose properties contradict each other. Here, cascading works on the principle of "the last one is the best". The easiest way to look at it is to look at an example.

.alert {
  color: gray;
}

.alert-error {
  color: red;
}
<p class="alert alert-error">Important message in red!</p>

Based on the principle of cascading, the browser will first see the .alert selector and set the text to gray. Next, it'll come across the .alert-error selector, which says to set the color to red. And the browser will simply override gray with red. The order of classes in HTML is irrelevant in this case. Even then, the color of the text

<p class="alert-error alert">Important message in red!</p>

will still be red. This illustrates the independence of CSS from HTML. If you swap the selectors in CSS, the resulting styles will also change.

.alert-error {
  color: red;
}

.alert {
  color: gray;
}
<p class="alert alert-error">Important message in red!</p>

Selector weight

During development, you'll encounter various situations in which some selectors have more weight than others. And their location in the CSS file doesn't really matter:

<textarea class="form-input"></textarea>
.form-input {
  height: 50px;
}

textarea {
  height: 200px;
}

How high will the <textarea> element be ? The correct answer is 50px since the class selector has a higher priority than the tag selector. But how do you set the height to 200px without introducing new classes? It's enough to substitute the name of the class as well:

.form-input {
  height: 50px;
}

textarea.form-input {
  height: 200px;
}

The <textarea> element will now be set to 200px high. This happened because the priorities add together within a single selector. To better understand how this adding up works, imagine that the total weight of the selector is determined by three figures, where:

  1. The first digit shows the number of identifiers in the selector
  2. The second digit shows the number of classes in the selector
  3. The third digit shows the number of tags in the selector

It may sound complicated, but the concept is simple. Let's look at the last example:

<textarea class="form-input"></textarea>
.form-input {
  height: 50px;
}

textarea {
  height: 200px;
}
  • The .form-input selector consists of one class, so the second digit will be one, giving us 010
  • The textarea selector consists of a single tag. Therefore, we write one as the third digit of our number: 001

Visually, we can see that 010 > 001, so the properties within this rule have a higher priority. We wanted to fix that and therefore added to our selector:

.form-input {
  height: 50px;
}

textarea.form-input {
  height: 200px;
}

Now the order of forces in the universe has changed slightly:

  • The .form-input selector consists of one class, so the second digit will be one, giving us 010
  • The textarea.form-input selector consists of one class and one tag. So, we write one in the second and third digits of our number: 011

010 < 011, which means the properties inside the textarea.form-input selector will have higher priority.

This approach will help you better understand how certain rules work, as well as why all developers are trying to avoid complex selectors as much as possible. As you gain experience, you'll be counting the weight less and less often in this way, and you'll understand how the priorities are set from the start.

Do it yourself

Create index.html and style.css files on your computer.

Inside the HTML, enter the following

<div id="main" class="text-white alert alert-warning">Some text</div>

and the following CSS styles:

div {
  width: 500px;
  height: 500px;

  background: #333333;
}

#main {
  color: white;
  width: 750px;
}

.text-white {
  color: white;
}

.alert {
  height: 350px;
  color: gray;
}

div {
  background: blue;
}

.alert-warning {
  background: #000000;
  color: yellow;
}

Analyze the result.


Аватары экспертов Хекслета

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending the form, you agree to Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.bookmate">Bookmate</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.healthsamurai">Healthsamurai</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.dualboot">Dualboot</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.abbyy">Abbyy</span>

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending the form, you agree to Personal Policy and Service Conditions

Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.