The State of CSS in 2026: What Actually Changed
CSS went through a period where every browser shipped different experimental features. That era is effectively over. The features that stuck changed how we write stylesheets — and the ones that didn't taught useful lessons.
What shipped and actually matters
Nesting (native)
.card { background: white; }
.card h2 { margin: 0; }
became:
.card {
background: white;
& h2 { margin: 0; }
}
Native nesting eliminates the reason many teams reached for Sass. The syntax is simpler, there is no build step, and the cascade still works normally.
Container queries
Instead of "if the viewport is narrow, change the layout," you write "if the container is narrow, change the layout." This solved a real architectural problem that media queries never addressed.
:has()
The "parent selector" that developers asked for since 1998. :has(.empty) { } styles a container only when it contains an empty element. Simple, obvious, powerful.
Cascade layers (@layer)
Explicit control over specificity without !important wars. Define layers, import third-party styles into a low-priority layer, and your component styles win predictably.
What shipped but mostly didn't matter
- Anchor positioning: technically impressive, almost no one uses it for real UIs.
- View transitions API (CSS part): great for slideshows and single-page apps; the CSS surface is narrow.
- @scope: the idea is right, but standard class scoping already covers most real needs.
What the tooling shift looked like
The bigger change isn't a feature — it's that the design-system ecosystem converged on:
- component-level styles with container queries
- layer-organized third-party imports
-
:has()for conditional styling - native nesting for organization
Most utility-first frameworks adopted these patterns. Most teams stopped fighting the cascade.
What to do if your CSS feels outdated
- Replace your Sass nesting with native CSS nesting.
- Convert "viewport breakpoints" to container queries wherever a component is reused at different sizes.
- Use
@layerto tame third-party stylesheet conflicts. - Replace JavaScript parent/child detection with
:has().
The language is mature enough that the best code is shorter, clearer, and more portable than it was five years ago.
Top comments (0)