Why Isn’t Your CSS Working? Understanding Cascading

CSS stands for Cascading Style Sheets. As the name suggests, a Style Sheet is a file used to style your web page. (Fun fact: the file extension for CSS is simply .css—just like its acronym with a dot in front!) With CSS, you can apply styles to elements on your webpage using CSS Selectors, which target HTML elements based on their attributes, classes, IDs, or other properties. CSS allows you to design beautiful websites and even animate elements to enhance user interaction. Now that we understand the “Style Sheet” part—short and crisp—let’s break down the Cascading aspect. This is Part Two of our “Why Isn’t Your CSS Working?” series. In the previous article, we explored specificity in depth. Now, it’s time to apply that knowledge to better understand cascading—and how both work together to determine which style rules win. I’ve explained cascading through an investigative, real-world approach—so it feels more practical and relatable, not just theory. Although cascading and specificity are theory-heavy topics, this approach will help you actually understand and apply them, rather than just memorize the rules. At the end of this article you'll get the opportunity to strenthen your know with a quiz - I also provided the answer and its explaination If you're already familiar with specificity, then you're good to go If not, I highly recommend checking out my previous article: Why Isn't Your CSS Working? Understanding Specificity Table of Contents The Cascade: Why Order Matters 1. Cascading Rule #1: Source Order (Last Rule Wins) 2. Cascading Rule #2: Higher Specificity Overrides Source Order 3. Cascading Rule #3: Importance of Rules 4. Cascading Rule #4: Origin of Styles 5. Contextual Importance: Inline Styles > All Difference Between Cascading and Specificity How Cascading and Specificity Both Are Soulmates Bottom line Quick Quiz: Strengthen Your Understanding of the Cascade Wrapping Up 12. SOLUTION OF THE QUIZ The Cascade: Why Order Matters Which color do you think will be applied to the .text class—red or blue? Let’s check the browser to see for ourselves: Wait, blue is applied—but what happened to red? To understand this, let’s inspect the element using the browser’s DevTools. I’m using Chrome DevTools. As you can see, the .text class with color: red; is crossed out, meaning the browser ignored it, and color: blue; is applied instead. And this brings us to: 1. Cascading Rule #1: Source Order (Last Rule Wins) If two rules have the same specificity targeting the same element, the one that appears later in the stylesheet will override the earlier one. How does this happen? Browsers read styles from top to bottom, so the last matching rule takes precedence. When two rules have the same specificity and target the same element with the same selector, the one that appears later will override the earlier one. The browser disregards the earlier rule because the later one takes priority during rendering. 2. Cascading Rule #2: Higher Specificity Overrides Source Order Even if a rule appears later in the stylesheet, it won’t win if an earlier rule has higher specificity. Let’s say you define a class selector after an ID selector—but both target the same element. The browser will still apply the ID rule because its specificity is stronger. Let’s check what the browser renders. Let’s inspect it using the browser’s DevTools: As you can see, the ID selector’s color red is applied, and the class selector’s blue is crossed out. That’s because ID selectors are more specific—even if they appear earlier in the CSS file. I used the color property here, but the same rule applies to any property—like background, font-size, and more. 3. Cascading Rule #3: Importance of Rules Now you know that the browser prioritizes the last rule when the specificity and selector are the same—and that higher specificity can override the last rule. However, there’s one more way to override both: by using !important. Let’s investigate it by checking the code, the browser, and DevTools—just like before. You can see how we used !important in our stylesheet. color: red; is applied instead of color: blue;. The .text class with color: blue; is crossed out and ignored by the browser. That’s the power of the !important keyword. -- Behind the Scenes When a rule is marked as !important, it gets higher priority than other rules with the same specificity—regardless of their position in the stylesheet. The browser internally flags this rule as more important and ensures it’s applied over all others. However, when multiple !important rules conflict, the browser still uses: Specificity (higher wins) Source order (last one wins) ...to decide which one takes effect. Let’s See Conflicting !important Rules in Action Specificity (Higher Wins) w Let’s select the same element u

Apr 15, 2025 - 07:42
 0
Why Isn’t Your CSS Working? Understanding Cascading

CSS stands for Cascading Style Sheets. As the name suggests, a Style Sheet is a file used to style your web page. (Fun fact: the file extension for CSS is simply .css—just like its acronym with a dot in front!)

With CSS, you can apply styles to elements on your webpage using CSS Selectors, which target HTML elements based on their attributes, classes, IDs, or other properties. CSS allows you to design beautiful websites and even animate elements to enhance user interaction.

Now that we understand the “Style Sheet” part—short and crisp—let’s break down the Cascading aspect.

This is Part Two of our “Why Isn’t Your CSS Working?” series. In the previous article, we explored specificity in depth. Now, it’s time to apply that knowledge to better understand cascading—and how both work together to determine which style rules win.

I’ve explained cascading through an investigative, real-world approach—so it feels more practical and relatable, not just theory.

Although cascading and specificity are theory-heavy topics, this approach will help you actually understand and apply them, rather than just memorize the rules. At the end of this article you'll get the opportunity to strenthen your know with a quiz - I also provided the answer and its explaination

If you're already familiar with specificity, then you're good to go

If not, I highly recommend checking out my previous article: Why Isn't Your CSS Working? Understanding Specificity

Table of Contents

  1. The Cascade: Why Order Matters
  2. 1. Cascading Rule #1: Source Order (Last Rule Wins)
  3. 2. Cascading Rule #2: Higher Specificity Overrides Source Order
  4. 3. Cascading Rule #3: Importance of Rules
  5. 4. Cascading Rule #4: Origin of Styles
  6. 5. Contextual Importance: Inline Styles > All
  7. Difference Between Cascading and Specificity
  8. How Cascading and Specificity Both Are Soulmates
  9. Bottom line
  10. Quick Quiz: Strengthen Your Understanding of the Cascade
  11. Wrapping Up

12. SOLUTION OF THE QUIZ

The Cascade: Why Order Matters

Screenshot of CSS code demonstrating which property takes effect

Which color do you think will be applied to the .text class—red or blue?

Let’s check the browser to see for ourselves:

Screenshot of a webpage demonstrating applied CSS

Wait, blue is applied—but what happened to red? To understand this, let’s inspect the element using the browser’s DevTools. I’m using Chrome DevTools.

Screenshot of debugging CSS with Chrome DevTools

As you can see, the .text class with color: red; is crossed out, meaning the browser ignored it, and color: blue; is applied instead. And this brings us to:

1. Cascading Rule #1: Source Order (Last Rule Wins)

If two rules have the same specificity targeting the same element, the one that appears later in the stylesheet will override the earlier one.

How does this happen?

  • Browsers read styles from top to bottom, so the last matching rule takes precedence.
  • When two rules have the same specificity and target the same element with the same selector, the one that appears later will override the earlier one.
  • The browser disregards the earlier rule because the later one takes priority during rendering.

2. Cascading Rule #2: Higher Specificity Overrides Source Order

Even if a rule appears later in the stylesheet, it won’t win if an earlier rule has higher specificity.

Let’s say you define a class selector after an ID selector—but both target the same element.

The browser will still apply the ID rule because its specificity is stronger.

Screenshot of CSS showing ID selector defined before class selector

Let’s check what the browser renders.

Screenshot of a webpage showing red color applied due to ID selector

Let’s inspect it using the browser’s DevTools:

Screenshot of DevTools showing class rule crossed out and ID rule applied

As you can see, the ID selector’s color red is applied, and the class selector’s blue is crossed out.

That’s because ID selectors are more specific—even if they appear earlier in the CSS file.

I used the color property here, but the same rule applies to any property—like background, font-size, and more.

3. Cascading Rule #3: Importance of Rules

Now you know that the browser prioritizes the last rule when the specificity and selector are the same—and that higher specificity can override the last rule.

However, there’s one more way to override both: by using !important.

Let’s investigate it by checking the code, the browser, and DevTools—just like before.

Screenshot of CSS code demonstrating the specificity of  raw `!important` endraw

You can see how we used !important in our stylesheet.

Screenshot of a webpage demonstrating applied CSS with  raw `!important` endraw

color: red; is applied instead of color: blue;.

Screenshot of debugging CSS with Chrome DevTools for  raw `!important` endraw

The .text class with color: blue; is crossed out and ignored by the browser.

That’s the power of the !important keyword.

--

Behind the Scenes

When a rule is marked as !important, it gets higher priority than other rules with the same specificity—regardless of their position in the stylesheet.

The browser internally flags this rule as more important and ensures it’s applied over all others.

However, when multiple !important rules conflict, the browser still uses:

  • Specificity (higher wins)
  • Source order (last one wins)

...to decide which one takes effect.

Let’s See Conflicting !important Rules in Action

Specificity (Higher Wins) w

Let’s select the same element using two class selectors and one ID selector—and mark all of them !important.

Screenshot of CSS with conflicting !important rules using class and ID selectors

Let’s see in the browser which one wins.

Screenshot of rendered webpage showing which style is applied

Now, let’s inspect the styles in DevTools and see what happened to the other rules.

Screenshot of DevTools showing crossed out styles

After following along this far, you’ve probably already guessed it—the other rules have been crossed out.

Here, the browser applied the style based on specificity.

Although all rules had the !important flag, the ID selector had the highest specificity, so its style (color: red;) was applied.

Source Order (last one wins)

What happens if we comment out the rule with the ID selector? Let’s find out.

Screenshot of CSS with ID selector rule commented out

Let’s check the browser to see which rule gets applied.

Screenshot of webpage showing green color applied

Color green is applied—now let’s inspect it in DevTools.

Screenshot of DevTools showing final applied rule and crossed out rule

Oh! It’s source order at work—since the ID rule is commented out, the browser applied the last !important rule it found. The earlier one was crossed out.

Pitfall: Don’t overuse !important, or debugging will become a nightmare!

Now that you have a solid understanding of source order, specificity, and importance, it’s time to move on to the next rule, which is:

4. Cascading Rule #4: Origin of Styles

I am going to show you one of the interesting things about the browser.

Screenshot of a webpage demonstrating default style with anchor tag

Screenshot of a CSS code demonstrating browser's default CSS

As you can see, I did not apply any style to the anchor tag, but it already comes with blue color and underline. But why?

Wait for a second — don’t think too much. I’ll explain it soon, but first, have a look at the image below:

Screenshot of DevTools demonstrating browser’s default styling

Did you notice that?

a:-webkit-any-link {
    color: -webkit-link;
    cursor: pointer;
    text-decoration: underline;
}

The browser styled it by itself — what we call user-agent (browser default) styles.

Styles can come from:

  • the browser (user-agent styles),
  • a user’s custom settings, or
  • your CSS file (Author styles).

And usually, Author styles override user-agent styles.

Here’s an illustration:

Screenshot of a CSS code demonstrating Author styles

As you see, I applied two properties that changed the color to purple and removed the underline.

Screenshot of a webpage demonstrating Author styles applied to the anchor tag

Congratulations, it worked!

Screenshot of DevTools showing that Author styles override browser styles

It overrode the user-agent styles — meaning the browser default styles — through my custom stylesheet. However, notice that it didn’t override cursor: pointer; because I didn’t write any rule for cursor, so the browser kept it.

That’s the full story on Cascading Rule #5: Origin of Styles.

When styles are defined by the Author, they override the user-agent styles because the specificity of Author styles is higher.

Note: Every browser has its own default style on elements, so different browsers style elements differently.

5. Contextual Importance: Inline Styles > All

Inline styles (e.g., style="color: red;" directly on an element) are more specific than anything in your stylesheet — unless something in your stylesheet uses !important and has higher specificity.

Let’s see it in action:

Combined ID and class selector used

We used a combined ID and class selector for higher specificity, giving the color property the value goldenrod.

Inline style applied with color red

Now we defined inline CSS with the style attribute and gave the value for the color property as red. Let’s check out the browser:

Browser showing red text

Inline CSS won because it has the highest specificity. Let’s inspect in DevTools:

DevTools showing inline style winning

Oh no! The combined ID and class selector:

#text_id.text {
    color: goldenrod;
}

Lost to:

element.style {
    color: red;
}

Which is inline CSS.

But here’s the catch — look at this:

!important used with goldenrod color

We marked the CSS with the !important keyword. Let’s see the result in the browser:

Browser showing goldenrod text due to !important

!important overrode the inline CSS. Don’t believe me? Let’s check in DevTools:

DevTools showing !important winning over inline

The !important rule overrides even the highest specificity like inline CSS — as I told you earlier in

3. Cascading Rule #3: Importance of Rules:

The browser internally flags this rule as more important and ensures it’s applied over all others.

No matter what the specificity is — if a rule is flagged with !important, it wins.

However, by now you understand that inline CSS has the highest specificity among all — unless !important steps in.

That’s the end of this article!

Just kidding haha!

I’m fully committed to helping you master CSS cascading rules. I won’t let you move on while you’re still confused — together, we’ll make sure you understand everything deeply and clearly.

In the previous part Why Isn't Your CSS Working? Understanding Specificity, I told you that Cascading and Specificity are soulmates.

But before we understand how, let’s first understand the difference between Cascading and Specificity.

Difference Between Cascading and Specificity

Both Cascading and Specificity help the browser decide which CSS rule to apply, but they play different roles in that decision:

  • Specificity is about how strongly a selector targets an element. Selectors with higher specificity override those with lower specificity.

    • ID selectors have more specificity than class selectors.
    • Class selectors are more specific than element selectors.
    • Inline styles have the highest specificity (unless !important is used).
  • Cascading is the algorithm the browser uses when there are conflicting styles. It evaluates multiple factors in a specific order:

    1. Importance (!important)
    2. Origin of styles (author, user, browser)
    3. Specificity
    4. Source order (last one wins)

In summary:

Specificity is just one piece of the Cascade puzzle.

When two rules conflict, the browser first checks for importance, then origin, then specificity, and finally source order to make the final decision.

How Cascading and Specificity Both Are Soulmates

You can't fully understand one without the other — that's why Cascading and Specificity are often called soulmates.

  • Cascading provides the rules.
  • Specificity provides the weight.

They work together to resolve conflicts and determine which CSS rule is the winner when multiple rules target the same element.

Think of Specificity as the "strength" of a rule and Cascading as the "judge" that decides which rule actually wins.

One sets the priority, and the other makes the final call.

Together, they ensure your styles behave as expected — or help you figure out why they don’t.

Why Are Media Queries Written at the End of a CSS File?

To understand why media queries (@media) are typically placed at the end of a CSS file, let’s walk through a simple, real-world example. This will help us see how cascading and source order influence which styles get applied by the browser.

We’ll begin by writing a media query for screens with a maximum width of 400px and styling a

element with the class .text.

Media query styles defined first in the CSS file

When we open this in the browser on a desktop screen (width greater than 400px), the media query does not apply. So, we see no visible changes from the .text class.

No styles are applied from the media query at desktop width

Inspecting the element in DevTools, we can see that the styles are coming from the body tag and the universal selector *.

DevTools show styles applied from body and universal selector

Now let’s shrink the screen size below 400px. The media query condition is now true, so the styles inside the media query apply.

Media query styles are applied on small screens

In DevTools, we can clearly see that the .text class styles from the media query—background-color: white and color: red—are now active.

DevTools show .text styles applied through media query

But what happens if we define the same .text class again, outside of the media query, and after it in the CSS file?

Styles for .text defined after the media query

Let’s look at the result on a desktop screen first.

On desktop, the latest .text styles are applied

Now let’s test it on a screen width below 400px, where the media query should apply.

Even on mobile, the last styles override the media query

Despite meeting the media query condition, the styles defined after the media query still apply. That’s because when two rules have the same specificity, the one that appears later in the stylesheet wins due to cascading and source order.

DevTools confirms this by showing that the media query styles are crossed out and overridden.

DevTools show media query styles crossed out

Now let’s update the media query and use an ID selector like #text, which is more specific than the .text class outside the media query.

Media query uses ID selector which is more specific

This time, when the screen width is under 400px, the styles inside the media query take effect, despite being written earlier in the file.

ID selector wins due to higher specificity on small screen

DevTools shows that the ID-based styles are applied and the class-based styles are overridden.

DevTools confirm ID selector applied, others overridden

When we return to desktop width, the ID selector condition no longer applies, so the .text class styles are once again active.

On larger screens, the class styles are applied again

And DevTools reflects this switch accurately.

DevTools show .text class styles applied at desktop width

From this, it becomes clear: even though media queries are conditional, they are still part of the CSS cascade. If a rule with the same specificity comes after a media query, it will override it—even if the media query condition is met.

That’s why it’s a best practice to write your media queries at the bottom of your CSS file. This way, they can override earlier styles and you don’t have to resort to unnecessarily increasing specificity.

Otherwise, your stylesheet becomes hard to manage as you constantly fight your own rules with repeated selectors.

So the conclusion is: we write media queries at the bottom so that the cascade works in our favor when using the same selectors with the same specificity.

Now that you understand how media queries and cascade order work together, here’s something to think about:

Why do we usually place the universal selector (*) at the top of a CSS file?

You already know its specificity, and now you understand how cascade order works. Give it a thought. If you’re not sure, feel free to search or ask me.

Bottom line

This article explains how cascading works in CSS and how it interacts with specificity to determine which style rules are applied. Here's a summary of the key points:

  • Cascading Style Sheets (CSS) is used to style web pages through selectors that target HTML elements.

  • The Cascade is the algorithm browsers use to determine which CSS rules to apply when there are conflicts.

  • Cascading Rule #1: Source Order – When rules have the same specificity and target the same element, the last rule defined in the stylesheet wins.

  • Cascading Rule #2: Specificity – Rules with higher specificity override those with lower specificity, regardless of source order (ID selectors > class selectors > element selectors).

  • Cascading Rule #3: Importance – Rules marked with !important override normal rules regardless of specificity or source order.

  • Cascading Rule #4: Origin of Styles – Styles can come from the browser (user-agent styles), user's custom settings, or author styles. Author styles typically override user-agent styles.

  • Cascading Rule #5: Inline Styles – Inline styles (written directly in the HTML) have higher specificity than styles in external stylesheets, unless overridden by !important.

  • Relationship between Cascading and Specificity – Specificity is just one part of the cascade. The browser evaluates conflicts by checking importance, origin, specificity, and source order—in that order.

  • Media Queries and Source Order – Media queries are conditional, but they still participate in the cascade. If a rule with the same specificity appears after a media query, it can override the media query styles—even when the condition matches. That's why we usually write media queries at the bottom of our CSS files: so they have the final say when adapting styles for different screen sizes without needing to increase specificity.

  • When debugging CSS issues, browser DevTools are invaluable as they show which rules are being applied and which are being overridden.

  • Overusing !important can lead to maintenance nightmares and should be avoided when possible.

Quick Quiz: Strengthen Your Understanding of the Cascade

Question:

What color will the paragraph text render in the browser?

 class="message">Hello, world!

And the CSS:

/* style.css (linked in the HTML head) */
.message {
  color: green;
}


Options:

  • A) Green
  • B) Blue
  • C) Red
  • D) Red with !important, so it overrides the others

Wrapping Up

That's the end of this Part Two article of the "Why Isn't Your CSS Working?" series.

Here, we've covered cascading in depth — exploring how browsers determine which styles to apply when rules conflict.

But the most important takeaway is how Cascading and Specificity work together as soulmates of CSS — one providing the rules, the other providing the weight.

In the previous article - Why Isn't Your CSS Working? Understanding Specificity, we mastered specificity. Now, with both pieces of the puzzle, you're equipped to solve almost any CSS styling mystery you encounter.

In the next part of this series, we will be looking at Common Pitfalls and Best Practices to help you avoid frustrating debugging sessions and write more maintainable CSS.

I hope this helped you in your web development journey.

If you have any confusion, corrections, or suggestions, feel free to drop a comment below!

Thanks for reading.

SOLUTION OF THE QUIZ

Answer:

➡️ D) Red with !important, so it overrides the others

Explanation:

Even though all the selectors have the same specificity (just a class selector), the cascade takes into account source order and importance.

Here's how the rules stack up:

  1. style.css sets the color to green.
  2. An internal

    This site uses cookies. By continuing to browse the site you are agreeing to our use of cookies.