Modern CSS Without Frameworks: Native Nesting, Cascade Layers, and Design Tokens
After years of CSS-in-JS and utility frameworks, native CSS quietly caught up. A practical look at the features that finally let me delete the toolchain and write plain stylesheets again.
I spent five years writing CSS through abstractions: Sass, then CSS Modules, then a utility framework, then back to CSS-in-JS. Every step solved a real problem. Every step also added build complexity, runtime cost, or both.
Native CSS in 2026 makes most of those layers redundant. Here’s the stack I shipped this portfolio with.
Native nesting replaces the preprocessor
.card { padding: var(--space-4);
.card__title { font-family: var(--font-family-display); }
&:hover { border-color: var(--color-border-accent); }
@media (min-width: 720px) { padding: var(--space-6); }}No Sass, no PostCSS plugin. The browser parses this directly. The mental model matches BEM perfectly: every element, modifier, and breakpoint sits inside the block it belongs to.
Cascade layers end specificity wars
@layer reset, tokens, base, components, utilities; declares the order before any rule is written. A utility class never has to fight a component selector — its layer simply wins. Specificity inside a layer still matters; specificity across layers does not.
Design tokens as custom properties
:root { --color-accent-primary: #3bc7ff; --space-4: 1rem; --radius-md: 0.5rem;}One file, themable at runtime, zero build cost. Dark mode and brand variants become a matter of swapping a --color-* set under a media query or a class.
The toolchain wasn’t wrong — it was a bridge. The bridge is no longer load-bearing for most projects. Cross it back.