Modern CSS Features (2024–2025)
This page covers the newest CSS capabilities that are now production-ready. These are the features AI tools generate, modern browsers support, and that will shape how CSS is written going forward.
1. CSS Nesting (Native &)
CSS nesting — like Sass, but built into the browser. No preprocessor needed. ~96% browser support.
/* ❌ Before: Repetitive flat selectors */
.card { background: var(--color-surface); }
.card:hover { box-shadow: var(--shadow-lg); }
.card .card__title { font-size: 1.5rem; }
.card .card__title:hover { color: var(--color-primary); }
/* ✅ After: Nested CSS */
.card {
background: var(--color-surface);
&:hover { box-shadow: var(--shadow-lg); }
.card__title {
font-size: 1.5rem;
&:hover { color: var(--color-primary); }
}
.card__body { padding: var(--space-6); }
}
Nesting with Pseudo-Classes
.btn {
padding: 0.75rem 1.5rem;
&:hover { background: var(--color-primary-dark); }
&:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 3px; }
&:disabled { opacity: 0.5; cursor: not-allowed; }
&.btn--outline {
background: transparent;
border: 2px solid var(--color-primary);
&:hover { background: var(--color-primary); color: white; }
}
}
Nesting Media Queries
.hero {
padding: 4rem 1rem;
@media (min-width: 768px) {
padding: 6rem 2rem;
}
@media (min-width: 1024px) {
padding: 8rem 4rem;
}
h1 {
font-size: clamp(2rem, 5vw, 5rem);
}
}
2. :has() — The Parent Selector
:has() lets you style a parent based on its children — the long-awaited "parent selector". ~88% support.
/* Style a form section if it contains an invalid input */
.form-group:has(input:invalid) {
border-color: var(--color-danger);
}
/* Card with image gets less top padding */
.card:has(img) { padding-top: 0; }
/* Navigation item with an open dropdown */
.nav__item:has(.dropdown.is-open) { color: var(--color-primary); }
/* Label next to a required field */
label:has(+ input:required)::after { content: ' *'; color: var(--color-danger); }
/* Grid changes when it contains a featured item */
.post-grid:has(.card--featured) { grid-template-columns: 2fr 1fr 1fr; }
3. @layer — Cascade Layer Management
@layer gives you explicit control over the cascade — no more specificity wars. ~91% support.
/* Declare layer order first — lower = weaker */
@layer reset, base, components, utilities, wp-theme;
@layer reset {
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
}
@layer base {
body { font-family: var(--font-body); line-height: 1.6; }
:where(h1, h2, h3, h4) { font-family: var(--font-heading); }
}
@layer components {
.card { background: var(--color-surface); border-radius: var(--radius-md); }
.btn { padding: 0.75rem 1.5rem; border-radius: var(--radius-full); }
}
@layer utilities {
.text-center { text-align: center !important; }
.hidden { display: none !important; }
}
@layer wp-theme {
/* WordPress theme overrides — weakest within components but beats reset/base */
.entry-content p { max-width: 72ch; }
}
[!TIP]
!importantin a lower layer loses to normal rules in a higher layer. This means you can import a third-party stylesheet into aresetlayer and it will never beat your component styles — even without!important.
4. color-mix() — Programmatic Color Mixing
Mix two colors at the CSS level — great for dynamic theme generation. ~88% support.
:root {
--color-primary: hsl(245, 80%, 62%);
/* Create tints and shades from one base color */
--color-primary-10: color-mix(in oklch, var(--color-primary) 10%, white);
--color-primary-50: color-mix(in oklch, var(--color-primary) 50%, white);
--color-primary-90: color-mix(in oklch, var(--color-primary) 90%, black);
}
/* On-the-fly: mix with transparent for overlays */
.overlay { background: color-mix(in srgb, var(--color-primary) 20%, transparent); }
/* Mix two brand colors */
.gradient-mid { background: color-mix(in oklch, #6c63ff 50%, #f5a623); }
5. @property — Typed CSS Variables
Register CSS variables with a type — enables animating custom properties. ~84% support.
/* Without @property: hue can't animate because CSS doesn't know it's a number */
@property --hue {
syntax: '<number>';
initial-value: 245;
inherits: false;
}
@property --gradient-angle {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
/* Now these animate smoothly */
.rotating-gradient {
background: linear-gradient(var(--gradient-angle), #6c63ff, #00ff87);
animation: rotate-gradient 4s linear infinite;
}
@keyframes rotate-gradient {
to { --gradient-angle: 360deg; }
}
6. CSS Subgrid
Subgrid lets children of a grid item inherit the parent grid's tracks — aligning elements across nested containers. ~88% support.
.card-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
}
/* Cards use the parent grid's columns internally */
.card {
display: grid;
grid-row: span 3;
grid-template-rows: subgrid; /* ← The key: inherit parent row tracks */
}
/* Now all cards' inner rows align across the grid */
.card__image { } /* Row 1 — same height across all cards */
.card__body { } /* Row 2 — same height */
.card__footer { } /* Row 3 — all footers on same baseline */
7. field-sizing: content — Auto-Sizing Inputs
Textareas and inputs that grow with their content. ~82% support.
/* Textarea grows as user types — no JS needed */
textarea {
field-sizing: content;
min-height: 3rem;
max-height: 20rem;
}
/* Input width fits its content */
input[type="text"] { field-sizing: content; min-width: 10ch; }
8. Anchor Positioning (Emerging)
CSS-native tooltip/popover positioning relative to any anchor element. ~78% support.
/* Anchor an element */
.trigger { anchor-name: --my-anchor; }
/* Position popover relative to anchor */
.popover {
position-anchor: --my-anchor;
position: absolute;
top: anchor(bottom); /* Align popover top with anchor bottom */
left: anchor(left); /* Align to anchor's left edge */
}
9. Feature Support Timeline Summary
| Feature | Browser Support | Use Now? |
|---|---|---|
| CSS Nesting | ~96% | ✅ Yes |
:has() | ~88% | ✅ Yes |
@layer | ~91% | ✅ Yes |
color-mix() | ~88% | ✅ Yes (with fallback) |
| Container Queries | ~89% | ✅ Yes |
| Subgrid | ~88% | ✅ Yes |
Scroll-driven animation-timeline | ~82% | ⚠️ With fallback |
@property | ~84% | ⚠️ With fallback |
| Anchor Positioning | ~78% | ⚠️ Experimental |
field-sizing | ~82% | ⚠️ With fallback |