Math functions: clamp(), min(), max()
Modern CSS ships tools that used to need juggling (or JavaScript). Let's start with the ones you'll reach for the most.
clamp(min, ideal, max) produces a fluid value that grows with the screen
but never drops below the minimum nor exceeds the maximum. Think of a bouncer with
two limits. It is the modern way to do responsive typography and spacing without
filling everything with media queries:
h1 {
/* never less than 1.5rem, nor more than 3rem; grows with the viewport width */
font-size: clamp(1.5rem, 4vw, 3rem);
}
min(a, b)takes the smaller of the values:width: min(90vw, 600px).max(a, b)takes the larger:padding: max(16px, 5vw).
Ratios with aspect-ratio
aspect-ratio sets the width/height ratio of a box without padding tricks:
.video {
width: 100%;
aspect-ratio: 16 / 9; /* the height is computed on its own */
}
The :has() selector — the "parent" that was missing
For years you begged for a "parent selector" and the answer was always the same:
it doesn't exist. Well, now it does, and it's called :has().
:has() selects an element based on its content or its siblings. It is the
first selector that looks "downward", something that seemed impossible:
/* a card that contains an image gets a different layout */
.card:has(img) {
display: grid;
grid-template-columns: auto 1fr;
}
/* a label whose input is invalid is painted red */
label:has(+ input:invalid) {
color: #b91c1c;
}
Container queries: responsive by container
Media queries look at the viewport; container queries
(@container) react to the size of the parent container. This way the same
component adapts wherever it is:
.panel { container-type: inline-size; }
@container (min-width: 400px) {
.card { flex-direction: row; }
}
Native nesting
CSS already allows nesting rules like in Sass, without compiling:
.menu {
background: #fff;
& a {
color: var(--primary-color);
&:hover { text-decoration: underline; }
}
}
The & represents the parent selector. Nesting brings the style closer to the
structure of the component and reduces repetition. Just don't get carried away
nesting six levels deep, or you'll recreate the exact mess we came here to avoid.