CSS has evolved dramatically in the past few years. Here are five techniques that are well-supported and production-ready.
1. The :has() Selector
The "parent selector" we've been waiting for:
/* Style a card differently when it has an image */
.card:has(img) {
grid-template-rows: 200px 1fr;
}
/* Style a form when any input is invalid */
form:has(:invalid) {
border-color: red;
}
2. CSS Nesting
Write nested rules without a preprocessor:
.card {
padding: 1rem;
& .title {
font-size: 1.5rem;
}
&:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
}
3. View Transitions API
Smooth page transitions with CSS:
::view-transition-old(root) {
animation: fade-out 0.3s;
}
::view-transition-new(root) {
animation: fade-in 0.3s;
}
4. Scroll-Driven Animations
Animate based on scroll position:
.progress-bar {
animation: grow-progress linear;
animation-timeline: scroll();
}
@keyframes grow-progress {
from { width: 0; }
to { width: 100%; }
}
5. CSS Layers (@layer)
Control specificity without hacks:
@layer base, components, utilities;
@layer base {
a { color: blue; }
}
@layer components {
.btn a { color: white; } /* Always wins over base */
}
These CSS features eliminate many reasons we used to reach for JavaScript or preprocessors. The platform is catching up, and it's beautiful.