Markdown Memoirs

20 Game-Changing CSS Features You Need to Master Now

September 28, 2025
By Aditya Mishra
CSS CSS3 Web Development Frontend Container Queries Nesting Modern CSS

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.

Let’s dive in!


1. @layer: Specifity Control

@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.

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.


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 Alone

You get:

Super Long Heading With One Word Alone

Cleaner. 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 viewport size.

.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 hsloklch) 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.