Are You Still Using Media Query? Try These Modern CSS Features!
Are You Still Using Media Query? Try These Modern CSS Features!
Media queries changed the web. But honestly, most of the time they’re a sledgehammer when you need a scalpel. Modern CSS has features that handle responsive design without breakpoints — and they’re more robust.
TL;DR: If your only tool is @media, everything looks like a breakpoint.
These features let elements respond to their own context instead of the
viewport.
1. clamp() — fluid typography without breakpoints
The old way:
h1 { font-size: 1.5rem; }
@media (min-width: 768px) {
h1 { font-size: 2rem; }
}
@media (min-width: 1200px) {
h1 { font-size: 2.5rem; }
}
The modern way:
h1 {
font-size: clamp(1.5rem, 2vw + 1rem, 2.5rem);
}
One line. The font smoothly scales between 1.5rem and 2.5rem based on
viewport width. No jumps at arbitrary breakpoints.
How clamp() works
clamp(MINIMUM, PREFERRED, MAXIMUM)
- If the preferred value is below the minimum → uses minimum
- If the preferred value is above the maximum → uses maximum
- Otherwise → uses the preferred value
The 2vw + 1rem formula is key: vw makes it scale with the viewport, while
+ 1rem ensures it never gets tiny on small screens.
2. Container queries — respond to the parent, not the viewport
Media queries ask “how wide is the screen?” But a card in a sidebar and the same card in a full-width section need different layouts regardless of screen size. Container queries fix this.
.card-wrapper {
container-type: inline-size;
container-name: card;
}
.card {
display: grid;
grid-template-columns: 1fr;
}
@container card (min-width: 400px) {
.card {
grid-template-columns: 120px 1fr;
}
}
Now the card switches to a two-column layout when its container is at least 400px wide — not when the viewport is. The same component works everywhere.
3. aspect-ratio — no more padding-bottom hacks
The old hack:
.video {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
height: 0;
}
.video iframe {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
The modern way:
.video {
aspect-ratio: 16 / 9;
width: 100%;
}
That’s it. The browser maintains the ratio automatically.
4. :has() — the “parent selector” we waited 15 years for
Want to style a form differently when it contains a required field? Or change a card’s layout when it has an image?
/* Style the form when it has a required input */
form:has(input:required) {
border-left: 3px solid var(--accent);
}
/* Shrink the heading when an image is present */
article:has(img) h2 {
font-size: 1.1rem;
}
No JavaScript, no extra classes. :has() lets you style a parent based on its
children.
5. gap with flexbox — no more margin tricks
/* Old way: margins everywhere */
.items > * {
margin-right: 1rem;
margin-bottom: 1rem;
}
.items > *:last-child {
margin-right: 0;
}
/* Modern way: just use gap */
.items {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
gap works with flexbox, grid, and even multi-column layouts now.
6. Logical properties — direction-aware CSS
Instead of margin-left / margin-right, use logical properties that adapt to
writing direction:
/* Old */
.card { padding-left: 1rem; margin-right: 0.5rem; }
/* Modern — works in LTR and RTL automatically */
.card { padding-inline-start: 1rem; margin-inline-end: 0.5rem; }
When should you still use media queries?
Media queries aren’t dead. Use them when the overall page layout needs to change — like switching from a sidebar to a stacked layout. But for component-level responsiveness, reach for container queries and fluid values first.
Quick reference
| Feature | Replaces | Use case |
|---|---|---|
clamp() | Multiple @media font sizes | Fluid typography, spacing |
| Container queries | @media (min-width) in components | Responsive components |
aspect-ratio | padding-bottom hack | Fixed-ratio boxes |
:has() | JS class toggling | Parent styling from children |
gap | Negative margins / :last-child | Spacing between items |
| Logical props | left / right | Direction-aware layouts |
Start replacing your media queries today — your CSS will be simpler, more reusable, and more maintainable.