You now know two of the browser’s tie-breakers, specificity and order. They are part of a longer list called the cascade. When several declarations compete for the same property, the browser applies these checks in order, and stops at the first one that finds a winner.
- Origin and importance. Declarations from the browser’s default stylesheet, from your site and from the user.
!importantflips the order. - Layer. If you use
@layer, the layer order decides. - Specificity. Higher wins.
- Source order. The later declaration wins.
For an ordinary site, only steps 3 and 4 matter day to day.
Where your styles sit
| Source | Strength |
|---|---|
| Browser defaults (the “user agent” stylesheet) | Weakest |
| Your stylesheet | Overrides the browser |
Inline style attributes | Overrides your stylesheet rules |
!important in your stylesheet | Overrides inline styles |
Remember this when your style looks right in your file and the page ignores it: check whether an inline style, an !important or a more specific selector is higher.
Inheritance sits below all of this
If no rule sets a property for an element, it may inherit the value from its parent. Any rule that targets the element directly, even a weak one, beats an inherited value. See CSS Inheritance.
<style>
body { color: #1a5276; }
p { color: inherit; }
.accent { color: #d94a00; }
</style>
<p>Inherits blue from body.</p>
<p class="accent">A direct rule beats inheritance.</p>
A short checklist for debugging
- Is the selector really matching? (Check the element in the inspector.)
- Is the declaration valid? (Look for a warning icon or a strikethrough with a typo.)
- Is something with higher specificity setting the same property?
- Is it later in the file?
- Is there an inline style or
!important?
Layers in one sentence
@layer reset, base, components; declares an order, and rules in later layers win over earlier ones regardless of specificity. It is worth learning when your project grows large.