Modern CSS: Practical Features You Can Ship Today
The pace of CSS innovation has picked up considerably, and many of the most interesting additions are already available in current browsers. The team at web.dev highlighted a set of these features in their CDS 2019 presentation; here's a practical look at what's usable right now, along with a preview of where the platform is heading.
Scroll Snap: Built-in Scroll Physics
scroll-snap-type gives native, touch-enabled scroll snapping with the browser handling inertia and deceleration. A typical horizontal gallery setup uses overflow-x: auto on the container, overscroll-behavior-x: contain to keep nested scroll areas from bubbling up to the page, and scroll-snap-type: x mandatory so the viewport always settles on the nearest snap point. Child elements declare scroll-snap-align: start to lock their left edge (in LTR text) as the target:
section {
overflow-x: auto;
overscroll-behavior-x: contain;
scroll-snap-type: x mandatory;
}
section > picture {
scroll-snap-align: start;
}
The mandatory keyword forces the snap even during fast flings; a proximity value is the softer alternative that only snaps when the user slows down near a point. Demos are also available for vertical and combined horizontal-and-vertical ("matrix") snapping.
Styling Parent Elements Based on Child Focus
:focus-within solves a long-standing accessibility gap: applying styles to a parent when any descendant has keyboard focus. Dropdown menus are the classic case—without it, a menu whose :hover state revealed its children would collapse the moment a keyboard user tabbed onto an item inside. :focus-within keeps the menu visible for the entire focus traversal:
.menu:focus-within {
display: block;
opacity: 1;
visibility: visible;
}

Tab through the linked demo and the menus stay open as focus moves between items, which is the behavior you'd expect from a native widget.
System Preference Queries: Media Queries Level 5
New prefers-* media queries let the browser act as a proxy for OS-level settings, giving CSS access to user preferences that previously had to be managed inside the app:
prefers-reduced-motionprefers-color-schemeprefers-contrastprefers-reduced-transparencyforced-colorsinverted-colors
These are a significant accessibility win, particularly for contrast. Before prefers-contrast, offering a high-contrast variant that still matched your brand required building a manual toggle into the UI; now the OS setting is directly detectable. Since these flags are independent, you can combine them—for example, a high-contrast dark theme tied to ambient light detection.
One important nuance from the presentation: reduced motion shouldn't be treated as "no motion." Users are expressing a preference for less animation, not zero animation; a restrained crossfade can be the appropriate response to prefers-reduced-motion, rather than removing all movement.
Logical Properties for International Layouts
Physical properties like margin-left and top assume top-to-bottom, left-to-right reading. That assumption breaks down quickly in a global app supporting multiple writing modes, where developers adjust dozens of layout rules per language and quickly accumulate a maintenance burden.
Logical properties redefine layout relative to the writing mode's flow:
- The block dimension runs perpendicular to lines of text—
block-sizemaps toheightin horizontal writing modes. - The inline dimension runs parallel to the text—
inline-sizemaps towidthin English.
The same naming extends to box properties: in English, block-start equals top and inline-end equals right. The practical payoff is that supporting a new language can be as simple as switching the writing-mode and direction on the root element, instead of rewriting physical offsets per component. Interactive demos let you flip the writing-mode on a live layout to see the effect.
Sticky Positioning, Three Effects
position: sticky keeps an element in normal block flow until it would scroll offscreen, then pins it at the top offset and releases it back to the flow when the user scrolls back up. The feature replaces a surprising amount of JavaScript with pure CSS. The presentation's demos show how small variations on markup and layout create distinctly different behaviors using nearly identical styles:
Sticky Stack
All sticky elements share a single container, so each subsequent element slides over the previous one as you scroll. Because the space in the flow is preserved, they all settle at the same stuck position.
Sticky Slide
Here the sticky elements are cousins in sibling containers. As an element reaches its container's lower boundary, it rises with the container at that edge, making elements appear to push each other up.
Sticky Desperado
The cousin structure remains, but each sticky element's container is placed in a two-column grid, changing how the parallax-style competition for the stuck position reads visually.
Backdrop Effects and Selector Shortcuts
The backdrop-filter property applies visual effects—blur, grayscale, and the like—to the area behind an element rather than to the element's own pixels. OS-style frosted glass panels, previously a mix of hacky CSS and JavaScript, now take a single property.
The :is() pseudo-class has been around for more than a decade but remains underused. It takes a selector list and matches any of them, which dramatically condenses repetitive rules:
button.focus,
button:focus {
…
}
article > h1,
article > h2,
article > h3,
article > h4,
article > h5,
article > h6 {
…
}
/* selects the same elements as the code above */
button:is(.focus, :focus) {
…
}
article > :is(h1,h2,h3,h4,h5,h6) {
…
}
Grid's Gap Comes Home to Flexbox
Grid has shipped gap for a while, giving the container ownership of inter-item spacing instead of relying on child margins (which tend to misbehave at container edges). Now flexbox is catching up with the same property, and it brings the familiar benefits:
- One spacing declaration replaces a family of margin rules.
- Conventions about which child owns spacing become unnecessary; the container handles it.
- The styling is clearer than selector tricks like the "lobotomized owl" approach.
Support varies—Firefox currently leads for flex gap—but the pattern is identical to grid, so the cost of adoption is minimal.
Houdini: Extending the Rendering Engine
Houdini is a set of low-level APIs that give JavaScript access to the browser's CSS engine. Instead of polyfilling custom features with script that parses after load and triggers a second render pass, Houdini code is registered in the first rendering cycle, making it faster and granting access to the CSS Object Model directly.
The umbrella covers multiple APIs; the talk highlights those with the widest current support—the Properties and Values API, the Paint API, and the Animation Worklet. For a living picture of implementation status, Is Houdini Ready Yet? tracks each API's progress across browsers. The demos in the talk start to show what becomes possible when the platform's primitives open up to developers.
The Next Batch of CSS Features
Beyond the headline properties, the talk closed with a speed round covering several other items on the CSS roadmap. Some of these are brand-new, while others are upgrades to existing tools. If you want the full walkthrough, the last section of the talk goes through them in detail.
Here is what is coming down the pipeline:
size: A shorthand property for setting bothwidthandheightin a single declaration.aspect-ratio: Lets you define a preferred ratio for elements that lack a natural one, making responsive scaling more predictable.- Comparison functions:
min(),max(), andclamp()will be usable on any CSS property—not just for sizing—to set numeric boundaries or responsive values. - Richer list markers: The existing
list-style-typeproperty will expand its accepted value range to include things like emoji and SVG graphics. - Two-value
display: Instead of compound keywords likeinline-flex, thedisplayproperty will accept two separate parameters for the outer and inner layout modes, offering clearer control. - CSS regions: A feature for directing content to flow into and out of a targeted, non-rectangular area on the page.
- CSS modules: JavaScript will gain the ability to import CSS as a module, returning a rich, structured object that is easier to manipulate programmatically.



