20 Modern CSS Features You’ll Wish You Knew Sooner
The last couple of years have been incredible for CSS. There have been so many new features that have come out, and they’re absolute game changers for how I write CSS.
So in this article, I’m going to be sharing with you my 20 favorite CSS features rapid fire, so you can get as much information as quickly as possible.
And if you want to go deeper on any of these, definitely check out their docs on MDN, almost every one of them is worth learning inside and out.
Here is the complete code example you can check:
Let’s dive in
1. @layer
@layer is honestly one of my favorite CSS features ever.
It’s been out for a while now, but not many people use it, and they really should.
It lets you create layers of specificity in your CSS.
So you can define something like:
@layer reset, theme, defaults, layout, components, utils;@layer reset {
* { margin: 0; padding: 0; }
}@layer theme {
:root {
--accent: #4f46e5;
}
}@layer utils {
* {
color: red;
}
}Because utils comes after components (or anything else), it will always win, even if the selectors are technically less specific.
You can even import directly into a layer:
@import url(”theme.css”) layer(theme);Super powerful, and super underrated.
Follow and Subscribe:
| Substack | Medium | The Conversion Brief | Community: Dev Community | Bluesky | LinkedIn | Hackernoon |
2. text-wrap: balance
Ever seen a heading with one awkward word on its own line?text-wrap: balance fixes that in one line.
h1 {
text-wrap: balance;
}It balances text across lines as evenly as possible.
So instead of:
Super Long Heading With
One Word
AloneYou get:
Super Long Heading
With One Word AloneCleaner. Prettier. Easier to read.
3. CSS Nesting
Nesting is finally in CSS — no preprocessor needed.
It lets you write cleaner, more structured styles.
.main-title {
font-size: 2rem;
@media (min-width: 800px) {
font-size: 3rem;
}
&.red {
color: red;
}
.subtitle {
font-size: 1.25rem;
}
}It’s like SCSS, but native.
4. Container Queries
Container Queries solve a huge problem:
They let you style components based on their container’s size, not the page.
.card {
container-type: inline-size;
}@container (min-width: 450px) {
.card {
flex-direction: row;
}
}@container (max-width: 449px) {
.card {
flex-direction: column;
}
}Perfect for component-based frameworks like React.
No more media query chaos.
5. Relative Colors
Relative Colors let you calculate new colors based on existing ones.
.button {
--bg: oklch(70% 0.2 250);
background: var(--bg);
border: 2px solid color-mix(in oklch, var(--bg) 85%, black);
}.button:hover {
background: color-mix(in oklch, var(--bg) 92.5%, black);
}You can also convert between color spaces (like hsl → oklch) on the fly.
Massively useful for theme systems.
6. :has() (Parent Selector)
:has() is basically the parent selector we’ve always wanted.
.input-group:has(input:valid) {
border-color: green;
}.input-group:has(input:invalid) {
border-color: red;
}This lets you style a parent based on its children.
It’s so good, and it’s supported in every major browser now.
7. @property
Custom properties are great — but they don’t animate by default.@property fixes that by letting you define type, inheritance, and defaults.
@property --my-color {
syntax: ‘<color>’;
inherits: false;
initial-value: red;
}.box {
--my-color: red;
background: var(--my-color);
transition: --my-color 0.5s;
}.box:hover {
--my-color: green;
}This makes custom props type-safe and animatable.
8. Subgrid
Subgrid took forever to arrive, but it’s finally here and amazing.
It lets a child grid inherit the tracks from its parent grid.
.parent {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
}.child {
display: grid;
grid-template-columns: subgrid;
gap: inherit;
}No more hand-syncing track sizes.
9. Multi-Value display
You can now define outer and inner display separately.
.box {
display: inline flex;
}inline= how it lays itself out (outer)flex= how it lays out children (inner)
It’s the clean way to combine layout behaviors going forward.
10. display: contents
This one’s sneaky but super useful.
It makes a wrapper element disappear visually while keeping its styles.
.wrapper {
display: contents;
}It lets the wrapper’s children behave like direct children of the flex/grid parent, perfect for fixing weird flexbox gap issues.
11. Logical Properties
Logical properties are just direction-aware versions of physical properties.
.box {
padding-inline-start: 1rem; /* instead of padding-left */
margin-block-end: 2rem; /* instead of margin-bottom */
}They respect writing modes and language direction, so your site works in RTL or vertical text automatically.
12. ::backdrop
The ::backdrop pseudo-element lets you style the background of a <dialog>.
dialog::backdrop {
background: rgba(0,0,0,0.5);
backdrop-filter: blur(4px);
}Add some fade animations and you’ve got beautiful modals.
13. transition-behavior: allow-discrete
and
14. @starting-style
These two work hand-in-hand for animating things that normally can’t animate, like display.
@starting-style {
dialog[open] {
opacity: 0;
scale: 0.8;
}
}dialog[open] {
transition: opacity .3s, scale .3s;
transition-behavior: allow-discrete;
opacity: 1;
scale: 1;
}Still missing in Firefox, but awesome for progressive enhancement.
15. field-sizing: content
This one is so cool: it lets textareas grow with content, no JS needed.
textarea {
field-sizing: content;
}Only Chromium supports it right now, but it doesn’t break anything elsewhere. Great little progressive enhancement.
16. @scope
@scope lets you scope styles to a specific subtree, like CSS Modules, but native.
@scope (.article) to (figure) {
h2 {
color: rebeccapurple;
}
}Or inline in a <style> tag:
<section>
<style scoped>
h2 { color: rebeccapurple; }
</style>
<h2>Only this one is purple</h2>
</section>Super handy for component libraries.
(Still missing in Firefox.)
17. anchor() Positioning
This one is my most hyped feature.
It lets you position elements relative to other elements, like real anchors.
.anchor {
anchor-name: --my-anchor;
}.tooltip {
position-anchor: --my-anchor;
top: anchor(bottom);
left: anchor(right);
}The browser handles all the math.
It’s still bleeding edge (no Firefox or Safari yet), but it’s going to be a game changer.
18. Container Style Queries
We saw size-based container queries earlier.
This is similar, but lets you query style values inside a container.
@container style(--accent: blue) {
.card {
border-color: var(--accent);
}
}It’s niche, but could be powerful for theme-based layouts later on.
19. interpolate-size: allow-keywords
Finally, we can animate from auto or max-content!
:root {
interpolate-size: allow-keywords;
}.panel {
height: 2.5rem;
transition: height .4s;
}.panel:hover {
height: max-content;
}Normally this just jumps instantly, now it animates smoothly.
So satisfying.
20. The Future of CSS Is Here
That’s it, 20 modern CSS features that are making writing CSS actually fun again.
Some of them are ready for production right now, and others are perfect for progressive enhancement.
Either way, they’re worth experimenting with, because they open up so many new possibilities.
— — — — — — — — — — — — — — — — —
Did you learn something good today?
Then show some love. 🫰
©
WordPress Developer | Website Strategist | SEO Specialist
Don’t forget to subscribe to Developer’s Journey to show your support.
Available for freelance projects on Upwork




