webroad.online
  1. 1Web
  2. 2HTML
  3. 3CSS
  4. 4JavaScript
  5. 5TypeScript
  6. 6Git
  7. 7Tooling
  8. 8React
  9. 9State management
  10. 10Next.js
  11. 11Forms
  12. 12Data and backend
  13. 13SEO
  14. 14Tailwind CSS
  15. 15Animations
  16. 16Testing
  17. 17Architecture
CSS · Lesson 1 of 8

Cascade, specificity, inheritance

What CSS is, how the winning rule is decided and what gets inherited.

Updated

What CSS is

CSS (Cascading Style Sheets) describes how the HTML looks. A CSS rule has a selector (who) and declarations (what):

.card h2 {            /* selector */
  color: navy;        /* property: value; */
  margin-bottom: 1rem;
}

The central problem of CSS: several rules can target the same element. Which one wins? The answer is the cascade.

The cascade — the order of the decision

When two declarations fight over the same property, the browser compares, in order:

  1. Importance — !important beats everything (avoid it; it's a sign something is wrong).
  2. The layer (@layer) — layers declared later win. Tailwind uses it internally.
  3. The selector's specificity.
  4. Source order — on a tie, the last rule wins.

Specificity

Every selector gets a score of the form (IDs, classes, elements). They're compared left to right — one class beats any number of elements, one ID beats any number of classes.

Selector Score Explanation
p (0, 0, 1) one element
.card (0, 1, 0) one class
.card p (0, 1, 1) class + element
nav a:hover (0, 1, 2) the pseudo-class counts as a class
[type="email"] (0, 1, 0) the attribute counts as a class
#header .logo (1, 1, 0) the ID beats everything below it
style="..." above all inline style
* (0, 0, 0) universal, no score

Special cases: :where(...) has specificity 0 (good for base styles that are easy to override); :is(...) and :not(...) take the specificity of their "strongest" argument.

The practical rule: use classes, avoid IDs in CSS and !important. That way all rules have similar scores and the order stays predictable.

Inheritance

Some properties pass automatically from parent to children, others don't:

Inherited (usually text) Not inherited (usually box)
color, font-*, line-height, text-align, visibility margin, padding, border, width, background, display

That's why you put font-family on body and it applies everywhere, while padding on body doesn't show up on every paragraph.

You can force it: inherit (take the parent's value), initial (the default value), unset.

Selector types

Type Example Selects
element p all paragraphs
class .btn elements with class="btn"
ID #app the element with id="app"
attribute [disabled], [href^="http"] by attributes
descendant .card p a p anywhere inside .card
direct child .menu > li only direct children
next sibling h2 + p the p right after an h2
pseudo-class :hover, :focus-visible, :first-child, :nth-child(2n) a state or position
pseudo-element ::before, ::after, ::placeholder a "virtual" part of the element
relational .card:has(img) the parent that contains something

Common mistakes

  • Long selectors (.page .main .content .card .title) — hard to override.
  • !important to "beat" a rule — it hides the real problem.
  • Styles on IDs.

Summary

  • The winner: !important → layer → specificity → order.
  • Specificity = (IDs, classes, elements); use classes.
  • Text is inherited, the box isn't.

Official sources

Exercises

Was this page helpful?

One tap — no account needed.