CSS has shipped more genuinely useful layout and styling primitives in the last three years than in the decade before it, and by 2026 the practical question for most teams isn't "is this supported" — it's "which of these should replace the JavaScript or Sass workaround we built before the native feature existed." This is a rundown of what's actually safe to use in production today, not a speculative wishlist.
Container queries are no longer "the new thing"
container-type and the @container at-rule shipped across all major engines back in 2023, and by now they're simply part of the standard toolkit for component-level responsive design — a card or widget adapts to the space its parent gives it, not the viewport. If you're still duplicating a component for sidebar vs. main-column placement because a media-query breakpoint never quite matched actual available width, that's the concrete signal to convert it to a container query instead.
.panel { container-type: inline-size; }
@container (min-width: 480px) {
.panel-body { grid-template-columns: 1fr 1fr; }
}
@supports not (container-type: inline-size) {
/* fallback for the rare unsupported engine */
.panel-body { grid-template-columns: 1fr; }
}
:has() — the parent selector
:has() lets you style an element based on what it contains or what follows it — something CSS genuinely couldn't do before without a JavaScript class toggle. .card:has(img) matches a card that contains an image; label:has(+ input:invalid) styles a label based on the validity state of its sibling input. It's supported across all current major browser engines and quietly eliminates a category of "add a class with JS just to style a parent" workaround.
Just because you can express complex conditional styling in a single selector doesn't mean every case should live there. If a :has() selector chain is doing something closer to business logic than styling, a data attribute set by your framework is often more maintainable than a deeply nested :has() chain.
Native nesting, color-mix(), and relative color syntax
Native CSS nesting removed a major reason to reach for Sass on new projects — you can nest selectors directly without a preprocessor, and it's supported everywhere current. color-mix() lets you blend two colors in a specified color space directly in CSS (color-mix(in oklch, var(--brand) 80%, white)), which replaces a lot of hand-maintained tint/shade color palettes. Relative color syntax (oklch(from var(--brand) l c h / 0.5)) lets you derive a new color from an existing one — adjusting just the alpha or lightness — without duplicating the base color value. Both are supported in current versions of all major engines, though relative color syntax landed later and is worth a @supports check if you need to support slightly older browser versions in your audience.
Scroll-driven animations
animation-timeline: scroll() and animation-timeline: view() let you drive a CSS animation's progress from scroll position instead of time — a progress bar that fills as the page scrolls, or an element that fades in as it enters the viewport — without a scroll event listener and manual `requestAnimationFrame` math in JavaScript. This shipped in Chromium-based browsers first and reached Firefox and Safari later; check current support for your audience before relying on it as the only implementation, and keep a reduced-motion fallback since scroll-driven effects should respect prefers-reduced-motion same as any other animation.
Features that land in Chromium often reach Firefox and Safari on a delay of anywhere from months to over a year. Before depending on something newer than container queries or :has() as a hard requirement, check actual current cross-engine support rather than assuming feature parity — caniuse.com and the MDN browser-compat-data are the two sources worth trusting over blog posts, including this one, since support tables change faster than articles get updated.
Anchor positioning — still maturing
CSS anchor positioning (anchor(), position-anchor) lets you position an element — a tooltip, a popover — relative to another element anywhere in the DOM, without JavaScript measuring bounding boxes. It's one of the more exciting layout additions on the horizon because it directly replaces a common JS library dependency (Floating UI, Popper), but cross-engine support was still uneven as of early 2026 — treat it as something to prototype and watch, not something to ship as your only implementation for a production tooltip system yet.
| Feature | Status (2026) | Replaces |
|---|---|---|
| Container queries | Fully shipped, safe to use | Component-specific media query hacks |
| :has() | Fully shipped, safe to use | JS class toggling for parent/sibling styling |
| Native nesting | Fully shipped, safe to use | Sass/Less for basic nesting |
| color-mix(), relative color syntax | Shipped, check older-browser needs | Manual tint/shade palette generation |
| Scroll-driven animations | Shipped in most, verify per engine | Scroll event listeners + rAF for scroll effects |
| Anchor positioning | Maturing, uneven support | Floating UI / Popper for tooltip positioning |
Wrapping up
The pattern across most of these features is the same: CSS is absorbing responsibilities that used to require a JavaScript library or a preprocessor. Container queries, :has(), and native nesting are solid enough to adopt without hesitation; scroll-driven animations and anchor positioning are close enough to watch closely and prototype, but still worth a support check before you remove the JS fallback entirely.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.