CSS Cascade and Rule Order: How Browsers Choose Styles

The CSS cascade is the system browsers use to decide which style wins when multiple rules target the same element. Understanding rule order helps you predict overrides, fix styles that seem to “not work,” and write CSS that is easier to maintain.

Quick answer: When multiple CSS rules apply, the browser compares importance, origin, specificity, and source order. If rules still tie after those checks, the later rule wins.

Difficulty: Beginner

You'll understand this better if you know: how CSS selectors work, what a stylesheet is, and the difference between classes, IDs, and element selectors.

1. What Is CSS Cascade and Rule Order?

The CSS cascade is the decision process browsers use to choose one computed style from many possible declarations. Rule order is part of that process, but it is not the only part.

In practice, the cascade is why a button might look different in two places, why one class overrides another, or why a style in your stylesheet seems ignored.

2. Why CSS Cascade Matters

The cascade is one of the most important parts of CSS because it allows styles to be layered instead of rewritten from scratch. This makes large stylesheets manageable and lets component styles, utility classes, and page-specific rules coexist.

It matters most when you are debugging conflicts. If a rule does not apply, the problem is often not the selector itself but the fact that another declaration has higher priority.

3. Basic Syntax or Core Idea

The cascade does not require special syntax, but understanding how it works begins with a simple rule. When two declarations affect the same property on the same element, the browser chooses one based on the cascade.

Minimal example

Here is a small example where two class rules set the same property. The later rule wins because both selectors have equal specificity.

.card {
  color: blue;
}

.card {
  color: red;
}

In this case, both rules target the same element and have the same selector strength. The second declaration wins, so the text becomes red.

What the browser compares

When two rules conflict, the browser considers them in this order:

  1. Importance, including whether a declaration uses !important.
  2. Origin, such as browser defaults, author styles, or user styles.
  3. Specificity, meaning how strongly the selector targets the element.
  4. Source order, which means the later declaration wins when all else is equal.

This is why cascade problems often involve more than simply “put the rule lower.”

4. Step-by-Step Examples

Example 1: Later rules override earlier equal rules

This example shows the simplest case: two identical selectors define the same property, and the later one wins.

p {
  font-size: 16px;
}

p {
  font-size: 18px;
}

The second rule wins because the selectors match equally and the later declaration appears later in the stylesheet.

Example 2: Higher specificity beats earlier source order

If one selector is more specific, it can override a rule that appears later.

button {
  background: gray;
}

.primary {
  background: green;
}

If a button element has the class primary, the class rule usually wins over the element selector because a class selector is more specific.

Example 3: Combined selectors can beat simpler selectors

Selectors with more matching parts are often stronger, which is useful when you want a context-specific override.

.nav a {
  color: black;
}

a {
  color: blue;
}

Links inside the navigation usually become black because .nav a is more specific than a plain a selector.

Example 4: Source order resolves ties

When specificity is identical, source order is the final tie-breaker.

.notice {
  border-color: blue;
}

.notice {
  border-color: orange;
}

The later declaration wins, so the border becomes orange. This is why the order of rules in a stylesheet still matters even when selectors look the same.

5. Practical Use Cases

You will use the cascade whenever styles need to layer cleanly across a project. Common situations include:

The cascade is especially useful in real projects because it lets you create predictable style hierarchies without rewriting every selector.

6. Common Mistakes

Mistake 1: Assuming the last rule always wins

Many beginners think CSS is purely “last one wins,” but specificity can override source order. That misunderstanding leads to confusion when an earlier, stronger selector beats a later, weaker one.

Problem: The later rule does not apply because it is less specific than the earlier rule.

#site-header h1 {
  color: purple;
}

h1 {
  color: orange;
}

Fix: Use a selector with equal or higher specificity, or structure your CSS so the intended override is stronger.

#site-header h1 {
  color: purple;
}

header h1 {
  color: orange;
}

The corrected version works only if the new selector is strong enough to compete in the cascade.

Mistake 2: Using !important as the first fix

!important can force a declaration to win, but it often makes styles harder to override later. It is usually a sign that the cascade structure needs improvement.

Problem: The rule becomes difficult to override because !important changes its priority.

.modal {
  display: none !important;
}

.modal .is-open {
  display: block;
}

Fix: Remove !important and use a selector strategy or a class-based state that fits your design.

.modal {
  display: none;
}

.modal.is-open {
  display: block;
}

The corrected version is easier to maintain because the state class participates naturally in the cascade.

Mistake 3: Forgetting that inline styles have very high priority

Inline styles are not “magic,” but they often override regular stylesheet rules because they belong to the author origin with very strong precedence.

Problem: A stylesheet rule appears to do nothing because an inline style is winning.

<div class="alert" style="color: red;">
  Notice
</div>
.alert {
  color: green;
}

Fix: Move the styling into CSS when possible, or intentionally override the inline style with a more specific strategy if that is the right design choice.

.alert {
  color: green;
}

The corrected approach is more predictable because the element is styled from one place instead of competing with an inline declaration.

7. Best Practices

Practice 1: Prefer simple selectors that are easy to override

Overly specific selectors can trap you into writing even stronger selectors later. Simple selectors make the cascade work for you instead of against you.

/* Harder to override */
main section article h2 {
  margin-top: 0;
}

/* Easier to manage */
.section-title {
  margin-top: 0;
}

Using a class for the styling intent keeps the rule easier to reuse and override later.

Practice 2: Group related rules by layer or purpose

Even without advanced features, organizing CSS from broad to specific helps keep rule order understandable.

body {
  font-family: sans-serif;
}

.button {
  padding: 0.75rem 1rem;
}

.button.primary {
  background: rebeccapurple;
}

This structure makes it clear which rules are base styles and which are variations.

Practice 3: Use the cascade instead of repeating declarations everywhere

If several elements share a property, define it once in a shared rule and override only what changes.

.panel {
  border: 1px solid #ccc;
  padding: 1rem;
}

.panel.warning {
  border-color: crimson;
}

The shared rule creates a base style, and the modifier only changes the one property that needs to differ.

8. Limitations and Edge Cases

One common “not working” situation is a rule inside a media query that looks correct but never applies because the viewport is not wide enough. Another is expecting source order to override a more specific selector.

9. Practical Mini Project

Let’s build a small alert box system that demonstrates how the cascade creates a base style and two variants. The base rule provides shared styling, while more specific class combinations adjust the look for warnings and success messages.

.alert {
  padding: 1rem;
  border: 1px solid #999;
  background: #f8f8f8;
  color: #222;
}

.alert.warning {
  border-color: #d97706;
  background: #fff7ed;
}

.alert.success {
  border-color: #16a34a;
  background: #f0fdf4;
}

This works because every alert gets the base styling first, and then the more specific variant rule changes only the parts that need to differ. The cascade lets the shared style stay DRY while still allowing clear overrides.

10. Key Points

11. Practice Exercise

Try this exercise to test your understanding of rule order and conflict resolution.

Expected output: The base card style should apply first, the later equal-specificity rule should override the background, and the featured variant should override the border.

Hint: Use the same selector twice to see source order, then increase selector strength with an additional class to see specificity win.

Solution:

.card {
  background: white;
  color: #222;
  border: 1px solid #ccc;
}

.card {
  background: #f5f5f5;
}

.card.featured {
  border-color: rebeccapurple;
}

12. Final Summary

The CSS cascade is the reason styles can be layered, overridden, and composed across a project without rewriting everything. It determines which declaration wins by comparing importance, origin, specificity, and finally source order.

Once you understand the cascade, debugging CSS becomes much easier. Instead of guessing why a style failed, you can ask the right questions: Is another rule more specific? Is there an !important declaration? Is the style coming from inline markup, a later stylesheet, or a more specific selector?

As you continue learning CSS, focus on writing selectors that are simple, predictable, and easy to override. That approach works with the cascade rather than against it, which makes your styles more maintainable as your project grows.