CSS Has Quietly Gotten Much More Powerful
A lot of UI logic that used to require JavaScript — responsive components based on their own size, parent-aware styling, complex layouts — can now be done in pure CSS. This means smaller bundles and fewer runtime re-renders for purely visual behavior.
Container Queries
Unlike media queries, which respond to the viewport, container queries let a component respond to the size of its own container — essential for truly reusable components placed in varying layouts.
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 120px 1fr;
}
}
The :has() Selector
Finally allows styling a parent based on its children — something CSS couldn’t do for decades.
/* Style a form group differently when it contains an invalid input */
.form-group:has(input:invalid) {
border-color: red;
}
/* Style a card differently when it contains an image */
.card:has(img) {
padding-top: 0;
}
Modern Layout with Grid subgrid
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.grid-item {
display: grid;
grid-template-rows: subgrid;
grid-row: span 3;
}
Subgrid lets nested grid items align to the parent grid’s tracks, solving a long-standing pain point in card layouts with uneven content heights.
Native Nesting
.card {
padding: 16px;
& .title {
font-weight: 600;
}
&:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
}
Scroll-Driven Animations
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
.reveal {
animation: fade-in linear;
animation-timeline: view();
}
Scroll-linked animations that previously required a JavaScript library like GSAP or Framer Motion can now be done natively for many common cases.
Browser Support Considerations
Container queries, :has(), and nesting have solid support across modern evergreen browsers. Always check current support on caniuse.com for your specific audience before relying on newer features without a fallback.
Conclusion
Modern CSS has absorbed a meaningful chunk of what used to require JavaScript. Before reaching for a library to solve a layout or responsive-styling problem, check whether container queries, :has(), or native nesting already solve it more simply.