Native CSS nesting & naming

Write component CSS with nesting

Lesson 8 of 20 · 11 min · Module 2: Selectors and the cascade

As a stylesheet grows, the rules for one component end up scattered. Native CSS nesting keeps everything about a component, including its variants and responsive tweaks, inside one block.

Start this lesson →

Free. No installation: you write and run the code in your browser, and it is checked automatically.

By the end, you’ll be able to…

  • Nest rules inside a component block
  • Use & for variants and states
  • Nest media queries next to the rules they change

The idea

Inside .card { … } you can write & h3 { … } for headings inside the card, &.is-featured { … } for a card that also has that class, and even @media rules. & stands for the parent selector. Unlike Sass, native nesting cannot glue suffixes: &__title does not create .card__title.

.button {
  padding: 8px 16px;
  &:hover { background: #24563c; }
  &.is-large { padding: 12px 24px; }
}

01One component, one block

Everything that styles the card now lives in one place. Delete or rename the component, and nothing is left behind elsewhere in the file.

02What & means

& is replaced by the parent selector. & h3 means .card h3, &.is-featured means .card.is-featured (no space: the same element), and &:hover means .card:hover.

.card {
  & h3 { }           /* .card h3 */
  &.is-featured { }  /* .card.is-featured */
  &:hover { }        /* .card:hover */
}

03Names still matter

Nesting does not replace good class names. Conventions such as BEM (.card__title, .card--featured) or simple state classes (.is-featured) keep selectors short and predictable. Write full class names, because native CSS cannot build .card__title from &__title.

Your turn

Rewrite the card styles as one nested .card block: keep its padding (24px), border, radius and background; nest & h3 with font-size: 20px and margin: 0 0 8px; nest & .card-meta with color: #6b7a63; nest &.is-featured with border-color: #2f6f4e and background: #eef6e5; and nest @media (max-width: 500px) that sets the padding to 16px.

What the checks look for

  • Card headings are 20px
  • Meta text is muted
  • The featured card has a green border
  • The featured card has a light green background
  • Other cards keep the neutral border
  • Cards use 24px padding on wider screens
  • Cards use 16px padding on small screens
  • The heading rule is nested inside .card
Try it in the editor →

Take this with you

Nesting groups a component’s rules; good names keep them simple.

Go a little further

Add a nested &:has(img) rule that removes the top padding when a card contains an image.

Learn HTML & CSS Intermediate for free

20 short lessons with real code and instant checks.

See the whole course →