Skip to main content

The Cascade, Specificity, and Inheritance

You now know there are three ways to write CSS: Inline, Internal, and External. But what happens when you accidentally apply two different styles to the same element?

The browser doesn't guess; it uses a strict set of rules known as the Cascade to determine which style wins. The Cascade is the process that combines three core concepts to resolve conflicts and apply the final styles:

  1. The Cascade: Where does the style come from?
  2. Specificity: How detailed is the selector?
  3. Inheritance: Does the element automatically get its parent's style?

1. The Cascade: Order and Source​

The Cascade is the primary system for layering styles. It decides the initial winner based on the origin and order of the stylesheet.

Source Order (The "Where" of the Style)​

Styles are prioritized based on their source. Think of it as a river flowing downhillβ€”styles closer to the element tend to flow last and have more power:

PrioritySourceDescription
HighestUser Styles (High Specificity)Styles applied directly by the user (e.g., accessibility settings).
2nd HighestAuthor's Styles (!important)Any rule in your CSS file marked with !important.
3rd HighestAuthor's Styles (Normal)Your External, Internal, and Inline styles (where Specificity rules the day).
LowestBrowser Default StylesDefault styles set by the browser (e.g., blue links, large <h1>).

The Role of Order:​

If two rules have the exact same Specificity (we'll cover this next) and come from the same source (e.g., two rules in your external stylesheet), the last rule defined wins.

styles.css
p { color: blue; } /* This rule is defined first. */
p { color: red; } /* This rule is defined last, so all <p> text will be RED. */

2. Specificity: Who is More Precise?​

When two or more selectors try to style the same element, the browser calculates which selector is more specific. The selector with the highest specificity score always wins, regardless of where it appears in the CSS file (unless it's overridden by !important).

Specificity is calculated by counting different types of selectors. Think of it as a four-digit number (A,B,C,D)(A, B, C, D), where the highest number in the most significant column wins.

Specificity Score Breakdown​

LetterSelector TypeExampleValue
AInline Styles<div style="...">1000
BIDs#main-nav100
CClasses, Attributes, Pseudo-classes.card, [type="text"], :hover10
DElements and Pseudo-elementsp, div, ::after1

Specificity Example​

Let's compare two conflicting selectors:

SelectorScore (A, B, C, D)TotalResult
h1(0, 0, 0, 1)1Loses
.header-title(0, 0, 1, 0)10Wins (The class is 10 times more specific than the element.)
SelectorScore (A, B, C, D)TotalResult
#sidebar p(0, 1, 0, 1)101Wins
.card .title(0, 0, 2, 0)20Loses (ID selector is 100 points, dominating the score.)
Specificity Tip

Never use Inline Styles and try to reserve ID selectors (#) for JavaScript targeting rather than styling, as their high specificity makes CSS harder to override and maintain.


The Power of !important​

The !important keyword is the nuclear option of CSS. When added to a declaration, it instantly makes that style rule override all other rules, regardless of specificity.

styles.css
/* This style will win over any ID, Class, or Element selector */
p {
color: green !important;
}

/* Even if an ID tries to override it, the !important rule wins */
#main-content p {
color: red; /* This will be ignored */
}
When to Avoid !important

Avoid using !important! It breaks the natural cascade flow and specificity rules, making your code extremely difficult to debug and maintain. Only use it in rare cases like:

  1. Overriding third-party library styles where you can't edit the source CSS.
  2. Utility classes (e.g., .u-hidden { display: none !important; }).

3. Inheritance: Borrowing Styles from Parents​

The final piece of the puzzle is Inheritance. Certain CSS properties are passed down (inherited) from a parent element to its child elements.

Inherited Properties​

Properties related to text and typography typically inherit:

  • color
  • font-family
  • font-size
  • line-height
  • text-align

Non-Inherited Properties​

Properties related to the Box Model and Layout do not inherit:

  • margin
  • padding
  • border
  • width / height
  • background-color

Inheritance Example​

index.html
<div style="font-family: Georgia, serif; border: 1px solid black;">
<p>This paragraph inherits the font from its parent <div>.</p>
<p style="border: none;">But it DOES NOT inherit the border or padding.</p>
</div>

The browser applies the font-family to the <p> elements, but since border is not inherited, the <p> tags will not have a border unless one is specifically declared for them.


Interactive Cascade Order Demo​

This interactive example shows how Specificity (ID vs. Class) and Source Order (last rule wins) determine the final style.

In the CSS panel, try changing the color values and observe which rule wins based on the selector's power.

Observations​

  1. The first paragraph's color is Purple because the ID selector (#intro-paragraph) has the highest Specificity score (100), overriding the Class (.main-text, score 10) and Element (p, score 1) selectors.
  2. The font-weight is Bold because it is set by the Class selector (Rule 2), and the ID selector (Rule 3) does not attempt to change the font-weight, allowing the inherited property to apply.
  3. The second paragraph (which has no class or ID) should take the color of the last p rule defined in the CSS if they were the only ones present. However, because the class and ID rules are present, they dominate the first paragraph.

The Cascade is a complex dance of Specificity first, and Source Order second.