Modern CSS Features You Should Be Using
Discover powerful CSS features that have gained widespread browser support and can dramatically simplify your stylesheets. From container queries to the :has() selector, here's what you need to know.
CSS has evolved dramatically over the past few years. Features that once required JavaScript or complex workarounds are now native to the language. Let's explore the most impactful modern CSS features you should start using today.
Container Queries
Container queries are a game-changer for component-based design. Unlike media queries that respond to the viewport, container queries let components adapt based on their parent container's size.
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 1rem;
}
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
}This means your card component can intelligently reflow whether it's in a narrow sidebar or a wide main content area - no JavaScript required.
The :has() Selector
Often called the "parent selector," :has() is one of CSS's most requested features. It lets you style an element based on its descendants.
/* Style a card differently if it contains an image */
.card:has(img) {
padding-top: 0;
}
/* Highlight form fields with errors */
.form-group:has(input:invalid) {
border-color: red;
}
/* Style navigation when a submenu is open */
nav:has(.submenu:hover) {
background: var(--nav-active-bg);
}Practical Example: Dynamic Form Labels
/* Float label up when input has content */
.input-group:has(input:not(:placeholder-shown)) label {
transform: translateY(-100%);
font-size: 0.75rem;
color: var(--accent-color);
}CSS Nesting
Native CSS nesting is finally here! No more preprocessors required for this beloved feature.
.card {
background: white;
border-radius: 8px;
& .header {
padding: 1rem;
border-bottom: 1px solid #eee;
}
& .content {
padding: 1rem;
}
&:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
@media (prefers-color-scheme: dark) {
background: #1a1a1a;
}
}Note: The
&is optional for most cases in modern browsers, but it's required when your nested selector starts with a letter (like element selectors).
Subgrid
Subgrid allows nested grid items to align with their parent grid's tracks. This solves the long-standing problem of aligning content across cards.
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
.card {
display: grid;
grid-template-rows: subgrid;
grid-row: span 3; /* Card spans 3 rows */
}Now all your card headers, content, and footers align perfectly across the row, regardless of content length.
The color-mix() Function
Create color variations without preprocessors or JavaScript:
:root {
--primary: #6366f1;
--primary-light: color-mix(in srgb, var(--primary) 70%, white);
--primary-dark: color-mix(in srgb, var(--primary) 70%, black);
--primary-transparent: color-mix(in srgb, var(--primary) 50%, transparent);
}
.button {
background: var(--primary);
&:hover {
background: var(--primary-dark);
}
&:disabled {
background: var(--primary-light);
}
}View Transitions API
While technically a JavaScript API, view transitions are CSS-powered and enable smooth page transitions:
/* Default crossfade for all elements */
::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 0.3s;
}
/* Custom animation for specific elements */
.hero-image {
view-transition-name: hero;
}
::view-transition-old(hero) {
animation: slide-out 0.3s ease-out;
}
::view-transition-new(hero) {
animation: slide-in 0.3s ease-out;
}Scroll-Driven Animations
Tie animations to scroll progress without JavaScript:
@keyframes fade-in {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-on-scroll {
animation: fade-in linear;
animation-timeline: view();
animation-range: entry 0% cover 30%;
}This creates a scroll-triggered fade-in effect that's buttery smooth and performant.
Wrapping Up
Modern CSS has become incredibly powerful. These features reduce our reliance on JavaScript for presentational logic and make our stylesheets more maintainable.
My recommendation? Start incorporating these features into your projects today. Browser support is strong (check caniuse.com for specifics), and they'll genuinely improve your development experience.
What's your favorite modern CSS feature? I'd love to hear how you're using these in your projects.