CSS

CSS in 2026: What Actually Changed and What Still Bites You

By Ken Key Aug 30, 2024 4 min read Updated Oct 16, 2026

CSS in 2026: What Actually Changed and What Still Bites You
The short answer

CSS in 2026 is mostly native: container queries, :has(), nesting, cascade layers, and oklch color all ship in every browser your customers use. The real gap is habit, not support. What still bites is subgrid, anchor positioning, and older Safari quirks.

Part of the complete web design guide.

On this page

CSS has changed more in the last four years than in the previous fifteen. The stuff I used to reach for a preprocessor or a JavaScript library to do is now native, and it works in every browser your customers actually use. Here’s what I’d tell a developer or business owner who hasn’t touched stylesheets since flexbox was the hot new thing.

I’ve been building sites for clients around Commack and across Long Island for a long time, and the practical gap between “what’s supported” and “what people still write” is wider than it’s ever been. So let’s close it.

Container queries are the biggest shift

Media queries ask “how wide is the viewport?” Container queries ask “how wide is the box I’m sitting in?” That sounds minor. It isn’t. It means a card component can restyle itself based on whether it’s in a sidebar, a three-across grid, or a full-width hero, without you writing three separate variants or passing breakpoints through props.

.card-wrap {
 container-type: inline-size;
}

.card {
 display: grid;
 grid-template-columns: 1fr;
 gap: 1rem;
}

@container (min-width: 30rem) {
 .card {
 grid-template-columns: 12rem 1fr;
 align-items: center;
 }
}

If you’re still maintaining a pile of .card--narrow and .card--wide modifiers, this replaces almost all of it. Support is universal now, so there’s no reason to hold back.

:has() finally killed a whole category of JavaScript

The parent selector shipped and it’s been stable for a while. You can now style an element based on what’s inside it. The classic example is a form field that should turn red when its input is invalid:

.field:has(input:invalid) {
 border-color: #c0392b;
}

.field:has(input:invalid) .hint {
 display: block;
}

/* Card with an image gets different padding */
article:has(img) {
 padding: 0 0 1.5rem;
}

/* Nav that contains an active link */
nav:has(a[aria-current="page"]) {
 border-bottom: 2px solid currentColor;
}

Before this, every one of those patterns meant a MutationObserver, an event listener, or a class toggled in a framework. Now it’s a selector. I’ve pulled real weight off several codebases just by deleting that plumbing.

Native nesting is fine now, with one caveat

CSS nesting is standardized and supported. The syntax that bit people early on was the ambiguity around element selectors, so the spec settled on requiring & when a nested selector starts with a type selector:

.menu {
 display: flex;
 gap: 1rem;
}

.menu a {
 color: inherit;
}

/* or nested */
.menu {
 & a {
 color: inherit;
 }
 &:hover {
 background: #f4f4f4;
 }
}

Note the leading & on & a. You can omit it for class and pseudo selectors, but keeping it everywhere is the habit I’d recommend. It reads the same and you never get surprised.

What I’d stop doing in 2026

  • Stop reaching for a preprocessor for variables. Custom properties do more, cascade properly, and can be changed at runtime from JavaScript or a media query.
  • Stop using float for layout. It hasn’t been the right tool since grid landed.
  • Stop shipping a reset you don’t understand. A short modern reset plus box-sizing: border-box covers nearly everything.
  • Stop writing vendor prefixes by hand. Autoprefixer and the browserslist config handle it, and most of the old prefixes are dead anyway.
  • Stop fighting the cascade with !important. If you need it, your specificity is the actual bug.

Color, units, and math got genuinely nicer

oklch() is the color space I default to now. It’s perceptually uniform, which means lightening a color by a fixed amount actually looks like the same amount of lightening across hues. That was never true with HSL.

:root {
 --brand: oklch(62% 0.19 250);
 --brand-light: oklch(82% 0.09 250);
 --brand-dark: oklch(42% 0.17 250);
}

.button {
 background: var(--brand);
 color: white;
 padding: 0.75rem 1.25rem;
 border-radius: 0.5rem;
}

.button:hover {
 background: var(--brand-dark);
}

And clamp() for fluid type means you can drop a lot of breakpoint-specific font sizing:

h1 {
 font-size: clamp(1.75rem, 1rem + 3vw, 3.5rem);
 line-height: 1.1;
}

That single line replaces three media queries and behaves better on the awkward widths in between.

Does any of this matter for a small business site?

Yes, but indirectly. Cleaner CSS means fewer bytes, fewer layout bugs, and less time billed when you want a change. If you’re paying someone to maintain a site, modern CSS is the difference between “swap the card layout” being a five minute edit and being a refactor. That’s real money either way.

If you’re weighing a rebuild versus patching what you have, it’s usually worth having someone look at the stylesheet before you commit to either. I do that kind of work as a Long Island web design developer, and the honest answer is often “your CSS is fine, here’s the three things to fix.”

Browser support in 2026

Container queries, :has(), nesting, oklch(), and clamp() are all baseline available. You do not need a fallback for any of them for a normal commercial site. The one thing I’d still check before using is anything tied to the newest view transitions and scroll-driven animations, which are shipping but with enough variation that I test per project rather than assume.

FAQ

Do I still need Sass or Less?

For most projects, no. Variables, nesting, and color functions are native now. The remaining reasons are large legacy codebases and teams that rely on Sass mixins heavily. New projects generally don’t need it.

Is it safe to use :has() on a site with older visitors?

Yes. It’s been supported across all major browsers for years. If a browser doesn’t understand the selector, it just ignores that rule, so nothing breaks, you only lose the enhancement.

How much does modernizing a stylesheet actually save?

It depends entirely on the starting point. I’ve seen files shrink by half after removing reset cruft and dead media queries, and I’ve seen files where the only win was readability. Anyone quoting you a percentage before looking at the code is guessing.

Have a project like this?

I do Long Island web design for Long Island businesses. If you need this done right, let’s talk.