CSS has evolved dramatically. Features that required JavaScript hacks or were impossible a few years ago are now native CSS. Here's a rundown of modern CSS features that are production-ready in Firefox and all modern browsers as of 2024.

CSS Nesting

No more BEM or repeated selectors — nest rules directly:

/* Old way */ .card { background: white; } .card:hover { box-shadow: 0 4px 20px rgba(0,0,0,0.1); } .card .title { font-size: 1.25rem; } .card .title:hover { color: blue; } /* Modern CSS nesting */ .card { background: white; &:hover { box-shadow: 0 4px 20px rgba(0,0,0,0.1); } .title { font-size: 1.25rem; &:hover { color: blue; } } @media (max-width: 768px) { padding: 12px; /* Media queries nested inside too */ } } 

Firefox 117+. No preprocessor needed.

:has() Relational Pseudo-Class

Style parents based on their children — the "parent selector" CSS has lacked for decades:

/* Card with an image → show image at full width */ .card:has(img) { padding: 0; } /* Form field with an error → turn label red */ .field:has(.error-message) label { color: red; } /* Navigation with a dropdown open → prevent scroll */ body:has(.dropdown:open) { overflow: hidden; } /* Table row on hover → highlight entire row */ tr:has(td:hover) { background: rgba(0,0,0,0.05); } 

Firefox 121+. Also available as :not(:has(X)) — elements without X.

CSS Grid subgrid

Children of a grid item can participate in the grandparent's grid:

.parent { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: auto auto; gap: 16px; } .card { display: grid; grid-row: span 2; grid-template-rows: subgrid; /* Use parent's row tracks */ } 

Without subgrid, all cards have independently-sized header/body. With subgrid, they align across the row.

Firefox 71+ (first browser to support it!).

color-mix()

Mix two colors in CSS without JavaScript or preprocessors:

:root { --color-primary: oklch(60% 0.2 230); } .button-light { background: color-mix(in oklch, var(--color-primary), white 30%); } .button-dark { background: color-mix(in oklch, var(--color-primary), black 20%); } /* Mix in different color spaces */ .cool { background: color-mix(in hsl, blue, green 50%); } .warm { background: color-mix(in srgb, red, yellow 40%); } 

Firefox 113+.

@layer Cascade Layers

Explicit priority for CSS blocks:

@layer reset, base, components, utilities; @layer reset { * { box-sizing: border-box; } } @layer base { a { color: blue; } } @layer components { .btn { /* ... */ } } @layer utilities { .hidden { display: none !important; } } 

Later layers override earlier layers regardless of specificity. Firefox 97+.

Container Queries

Style elements based on their container's size, not the viewport:

.card-container { container-type: inline-size; } @container (min-width: 480px) { .card { flex-direction: row; } } 

Firefox 110+.

@property Typed Custom Properties

Register custom properties with a type, enabling animation:

@property --progress { syntax: '<number>'; inherits: false; initial-value: 0; } .bar { transition: --progress 0.5s ease; } .bar.loaded { --progress: 75; } 

Firefox 128+.

CSS Logical Properties

Write direction-agnostic CSS that works for both LTR and RTL layouts:

/* Old */ margin-left: 16px; padding-right: 8px; border-top: 1px solid; /* Logical */ margin-inline-start: 16px; /* left in LTR, right in RTL */ padding-inline-end: 8px; /* right in LTR, left in RTL */ border-block-start: 1px solid; /* top in horizontal, left in vertical */ /* Even more concise */ margin-inline: 16px; /* left + right margin */ padding-block: 8px; /* top + bottom padding */ inset-inline: 0; /* left + right position */ 

Firefox 91+. Essential for internationalized sites.

oklch() Color Space

Perceptually uniform colors — consistent lightness across hues:

/* oklch(lightness chroma hue) */ :root { /* Same lightness, different hues — looks equally bright */ --red: oklch(60% 0.25 30); --blue: oklch(60% 0.25 250); --green: oklch(60% 0.25 140); } /* HSL 50% lightness of green looks much brighter than 50% lightness of purple */ /* oklch 60% lightness is visually consistent */ 

Firefox 113+.

Relative Color Syntax

Derive colors from other colors:

:root { --color: oklch(60% 0.2 230); } .lighter { background: oklch(from var(--color) calc(l + 20%) c h); } .darker { background: oklch(from var(--color) calc(l - 20%) c h); } .muted { background: oklch(from var(--color) l calc(c * 0.5) h); } 

Firefox 128+. Replaces Sass color functions entirely.

text-wrap: balance and text-wrap: pretty

Prevent typographic widows and orphans:

h1, h2, h3 { text-wrap: balance; /* Equal line lengths (max 4 lines) */ } p { text-wrap: pretty; /* No orphan words on last line */ } 

Firefox 128+.

Summary: What's Production-Ready in 2024

Feature Firefox Chrome Safari
CSS Nesting 117+ 112+ 16.5+
:has() 121+ 105+ 15.4+
Container queries 110+ 105+ 16+
subgrid 71+ 117+ 16+
@layer 97+ 99+ 15.4+
color-mix() 113+ 111+ 16.2+
@property 128+ 85+ 16.4+
oklch 113+ 111+ 15.4+

All of these are safe to use in production today without any build tools.