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 8 of 8

Modern CSS

Native nesting, :has(), :is/:where, logical properties, @layer.

Updated

What "modern CSS" means

In recent years CSS gained features that used to require Sass or JavaScript. Everything below works today in all major browsers — worth using, not just knowing.

Nesting — nested rules, natively

.card {
  padding: 1rem;

  & h3 { font-weight: 600; }        /* .card h3 */
  &:hover { border-color: gray; }   /* .card:hover */
  .dark & { background: black; }    /* .dark .card */

  @media (min-width: 48rem) {
    padding: 2rem;
  }
}

& = the parent selector. Like in Sass, but without a build step. Don't nest more than 2–3 levels — specificity grows and the CSS becomes hard to read.

:has() — "the parent selector"

For the first time, you can style an element by what it contains or by what happens after it:

.card:has(img) { padding-top: 0; }                       /* cards with an image */
.field:has(input:invalid) label { color: var(--danger); } /* the label of an invalid field */
form:has(:focus-visible) { outline: 2px solid; }          /* the form that has focus */
body:has(dialog[open]) { overflow: hidden; }              /* lock scrolling while a modal is open */

Many things that used to need state in React (a class on the parent) are now solved with CSS alone.

:is() and :where() — selector lists

:is(h1, h2, h3):hover { color: var(--accent); }
:where(ul, ol) { padding-left: 1rem; }
:is() :where()
Specificity that of the most specific argument zero
When shortening repeated selectors base styles / resets, easy to override

Logical properties

Instead of left / right / top / bottom, you describe the direction relative to the text. The layout then works automatically in right-to-left languages too (Arabic, Hebrew).

Physical Logical
margin-left / margin-right margin-inline-start / margin-inline-end
padding-left + padding-right padding-inline
padding-top + padding-bottom padding-block
width / height inline-size / block-size
top/right/bottom/left: 0 inset: 0

Tailwind has them: ps-4, pe-4, ms-auto, px-4 = padding-inline.

@layer — the cascade order, made explicit

@layer reset, base, components, utilities;

@layer components {
  .btn { padding: 1rem; }
}

Layers declared later win, regardless of specificity — see The cascade. Tailwind v4 is built on them (theme, base, components, utilities).

Other useful features

Feature What it does
clamp(), min(), max() fluid values without media queries
color-mix(in oklab, var(--c) 20%, transparent) colors derived from tokens
oklch() perceptually uniform colors — better palettes
container queries responsive by parent — Responsive
aspect-ratio a fixed ratio
text-wrap: balance / pretty balanced headings, no orphan words
accent-color the color of native checkboxes and radios

Summary

  • Native nesting with &; :has() styles by content; :where() = zero specificity.
  • Logical properties (padding-inline, inset) instead of left / right.
  • @layer controls the cascade; color-mix, oklch, text-wrap: balance for modern details.

Official sources

Exercises

Was this page helpful?

One tap — no account needed.