Around 2023, the CSS conversation was insufferable. Every conference talk pitched the same triad — container queries, subgrid, View Transitions — as the package that would change how we built layouts. Three years on, two of them earned the hype and one of them is still a footnote in our codebase. The story turned out to be less revolutionary than promised and more boringly useful, which is the best kind of story for a technology that has to ship.
Container queries: actually the thing
This is the one that quietly changed how we work. The viewport-based media query model was always a lie we agreed to: components do not know how big the viewport is, they know how much room they have on the page they're being dropped into. Container queries fixed that.
We have a card component that ships in three layouts depending on its container width. It sits in a 320px sidebar on one page, in a 600px grid cell on another, and in a full-bleed feature row on a third. The same component, with one stylesheet, looks correct in all three contexts. No JavaScript width checks. No duplicate component variants. No prop drilling about layout context. That used to be a real ongoing tax.
We write container queries on roughly every project now. Browser support has been universal since mid-2024 and we don't carry fallbacks anymore. The mental shift took about a month — designers had to stop thinking in viewport breakpoints and start thinking in component breakpoints — and once it landed, going back felt absurd.
View Transitions: a smaller thing, but real
The cross-document View Transitions API was the dark horse. Same-document transitions were nice, but the version that animates between full page loads is what made it interesting for us. We use it on multi-page sites built with htmx or just plain server-rendered HTML, and it gives them the smooth feel of a client-side router for the cost of about ten lines of code.
A photographer client of ours has a gallery site. Click a thumbnail, the thumbnail animates into the full image on the detail page. It's a real page load — fresh HTML, the URL changes, the back button works correctly, no JavaScript route handling — but it feels like a SPA. The previous version was a Next.js 14 app with about 600KB of JS to achieve the same effect. The current version is HTML with a single CSS rule and a meta tag.
We've shipped it on six projects now. Where it shines is on sites where the experience benefits from visual continuity — galleries, product detail flows, image-heavy editorial. On a dashboard or a docs site you'd never notice the difference. That's fine. It's a polish layer, not a foundation.
Subgrid: still weird
Subgrid is the one I keep wanting to like more than I do. The use case is real: a child element aligning its rows or columns to the parent grid. The implementation works. But the mental model required to plan a layout that uses it is genuinely harder than just nesting grids or reaching for flexbox.
Every time we use subgrid on a project, one of two things happens. Either I write it confidently because I just used it last week and remember the rules, or I open MDN and re-learn the rules because it's been a few months. Other CSS features I write from muscle memory. Subgrid never quite became muscle memory, and I've been writing CSS for fifteen years.
We use it sparingly — typically when we need a list of cards to align their internal sections (title, body, button row) across the row even though each card has different content lengths. That's the textbook case and subgrid handles it well. Outside of that, we usually find a way that doesn't involve it.
What else actually mattered
Native nesting. We've stopped reaching for Sass on small projects because the bits of Sass we used most — nesting and variables — are now native. Build pipeline removed. CSS file size down a touch. No regrets.
The :has() selector. The parent selector everyone wanted for two decades. We use it primarily in form validation styling and in a handful of layout cases where a parent needs to know about a child's state. Browser support has been complete since 2023 and it works.
Color functions. oklch() for color manipulation, color-mix() for blending. We define brand colors once and derive the hover, focus, and disabled states from them. Used to require a Sass function. Now requires one line.
What we still avoid
Anchor positioning. Conceptually interesting. In production we still use the Floating UI library because it handles edge cases the native API doesn't, and our designers don't want to know about whether the dropdown should flip or shift when there's no space below.
Scroll-driven animations. They work. They're cool. They also feel like an attractive nuisance — when we've used them, we've ended up regretting that the page scrolled differently than every other page on the site. We default to no animation, and that's mostly served us well.
Where we landed
Three years of new CSS made our codebase smaller and our designs more flexible. We removed Sass from most projects, removed a JavaScript dependency or two, and shipped things that look better with less code.
What didn't happen is the revolution. Pages still look like pages. Forms still look like forms. The web in 2026 looks remarkably similar to the web in 2023. The infrastructure underneath got better, and that's the whole shape of how CSS improvements actually arrive — quietly, in tooling, in the parts that aren't visible to the user. Which is exactly what you want from a styling language.