CSS’s Next Act: What’s Coming Down the Spec Pipeline
For front-end developers, CSS has long been a bit of a paradox. It’s powerful, but the language has historically moved at a glacial pace. Suddenly, that’s changing. With new specifications moving through the standards process and browser engines shipping features at a furious rate, the next few years promise to reshape how we write stylesheets. Guest Miriam Suzanne joins the show to map out the landscape, discussing the modular specs that are heading our way and how they’ll alter the daily practice of building for the web.
Why CSS Is Suddenly Speeding Up
The perception that CSS evolves slowly is rooted in past reality, but it doesn’t hold anymore. The language is now developed in modular chunks, with the CSS Working Group tackling independent features simultaneously—some smaller and self-contained, others larger and more architectural. That’s resulting in a flurry of new modules, each landing in browsers at its own pace. The era of waiting a decade for a single monolithic spec update is over; the web platform now improves in a steady stream of targeted releases.
Container Queries: The Reusable Component Era
One of the most anticipated specs is container queries, a system designed to end the limitations of viewport-based responsive design. Today’s media queries respond to the size of the browser viewport. But for reusable components embedded across different layouts, that’s guessing at context. Container queries work in reverse: components respond to the size of their parent container, no matter where they appear. That includes container query length units, which will let you specify dimensions relative to a container—like cqw and cqh—enabling a single card component to flow, scale, or rearrange predictably whether it’s dropped into a sidebar or a wide hero section.
Picking Your Priority: Cascade Layers
A second spec, cascade layers, tackles one of the biggest pain points on large projects: managing CSS precedence. Anyone who has battled specificity conflicts knows how messy it gets. Cascade layers give you explicit, project-defined buckets that dictate the priority of rules when a conflict occurs. Critically, they have a lower priority than specificity when matching a single rule—but this reordering of the cascade at a structural level means you can get predictable outcomes from your stylesheets without complex specificity hacks. It’s an attempt to form a reliable mental model that scales across teams of developers and stylesheets full of dependencies.
Reading the CSSWG’s Temperature
For those eager to track where these specs are headed, official sources are accessible. Shirley shares that the cascade layers, container queries, and scope specs are public working drafts, with explainers available on the web for deeper dives into the proposed mechanisms.
The Future Is Modular
Front-end development is being dragged forward by a growing need for reusable, cross-device components. These fresh modules signal a deeper shift—CSS is evolving past its positioning as a document styling system and into a full-featured app architecture tool. By decelerating the fast-moving parts of the browser and prioritizing elements that support dynamic composition, it’s setting up for a future where rapid page growth doesn’t have to mean exploding complexity.
Selectors: :is() and :where() in Practice
Among the newer selectors, :is() and :where() are worth knowing together, because they functionally do the same thing but handle specificity differently. Both accept a comma-separated list of selectors, matching any element that matches at least one entry in that list. A typical use is styling links inside any heading without repeating selectors: instead of writing every heading-combination selector, you can use :is(h1, h2, h3, h4, h5, h6) followed by a once. They also let you build compound matches, combining selectors inside and outside the pseudo-class.
The difference comes down to specificity. :is() takes the specificity of the most specific selector inside its list, so an id inside the parentheses raises the whole rule's specificity. :where() is the opposite: it always resolves to zero specificity. That makes :where() an intentional choice when you want to provide default styling that you don't want users to fight against later. It is a good fit for something like styling an audio element that has a controls attribute without adding weight to that rule.
Both selectors are also designed to be resilient. Currently, an invalid selector in a regular selector list causes the entire list to be dropped. Inside :is() or :where(), that same invalid selector gets skipped, but the rest of the list continues to match. That leverages CSS's natural fault-tolerance and keeps one bad entry from taking down the whole declaration.
There is also history here: these pseudo-classes grew partially out of requests for nesting support. They are a stepping stone in that direction because they provide a way to "de-sugar" nested selector syntax into a flat equivalent.
Focus and Marker Styling Refinements
The :focus-visible selector exposes browser logic around when focus should actually be visible. When navigating with a keyboard, you want a clear focus indicator; while clicking with a mouse, that same outline is often just visual noise. Instead of guessing, :focus-visible lets you write styles that apply only when the browser itself decides focus visibility matters. There is also :focus-within, which matches an element if it or any of its descendants has focus. For a form, that means you can style the entire component when one of its fields gets focus. Building a dropdown navigation system, for instance, becomes far more simple in CSS than was previously possible only with a lot of JavaScript.
For list markers, the new ::marker pseudo-element lets you style the bullet or numbering directly, removing the old practice of hiding markers with list-style: none and re-adding them with ::before or generated content. The available styling is currently limited to things like size, font, and font color, and can be composed with generated content as well, though support for that is broader than it initially was.
Aspect Ratio and Intrinsic Sizing
The aspect-ratio property puts an apparent end to the padding-top hack and the absolute positioning setup that was needed to make responsive media hold its ratio. You will be able to simply declare a ratio and have the element scale width and height proportionally. There's a connected recommendation: put the original width and height values back on replaced elements like <img> rather than stripping them out for a percentage-based CSS approach. The intrinsic ratio helps the browser reserve space before the image loads to prevent layout shifts, and flexbox and grid are designed to work with intrinsic sizing. As Jen Simmons has been explaining in the concept of intrinsic web design, the era of removing those dimensions is over; they became useful again once we stopped relying solely on percentages.
Subgrid and Container Queries
Subgrid extends nesting in CSS Grid. It allows a grid item to become a grid itself, but pass its row and column tracks back out to the parent grid, letting grandchildren sit on the same grid lines and columns as the outer layout. This is especially useful because grid layout otherwise operates on parent-child relationships. Subgrid lets contents of a grid item pass sizing information up to the grandparent, making the back-and-forth between content and context sizing complete.
Container queries are more widely anticipated and address a similar question building on that same context-content tension. A subgrid works fine because it doesn't affect output size, just alignment. Container queries risk an infinite loop: if an element can change its styling based on its own constraints, you can end up changing its size, which changes the constraint values, forever. The working system is essentially a way of cutting off that loop. The spec has, for a long while, been implemented step by step, and container queries are now close to solution. A working prototype exists in Chrome Canary, and the CSS Working Group is currently figuring out edge cases rather than foundational concepts. As "how should it fail" has become the true driver of the emergent specification, the remaining work lies in handling those edge cases, especially in unsupported or malformed situations.
Cascade Layers
Along with specificity and source order, cascade layers add an explicit control for the browser's cascade mechanism. You can think of them as distinct buckets that style declarations get sorted into, independent of the source order of the files that contain them.
The syntax is the @layer at-rule. You list your layers at the top of your document to declare both what they are and the order they should stack in. When you later create a layer by dropping its stylesheet into an @import, it gets slotted in at that original declared position. This is an effective way to import third-party style systems like Bootstrap:
- Order control: From the whole setup, you can define how Bootstrap wins over your layers, without needing to throw an
!importantor write extreme specificity selectors that were called for previously. - Self documentation: A single block listing layers makes the cascade intention visible and clear to anyone inspecting the file.
The Role of :is() in Fallbacks
Handling backward compatibility is the main drawback. Old browsers will ignore anything inside a layer rule entirely, which can break their declarations. Since :is() behaves resiliently and does not require a full layer, it actually makes a viable temporary polyfill that works in browsers that support :is() but not @layer, even if not for legacy browsers like IE 11.
Scoping and Future Work
Cascade layers have essentially diverged from the problem solved by scope, which is itself defined with the @scope rule in a draft spec. The proposal in its current form is the "donut scope" idea credited to Nicole Sullivan. In a @scope rule, root and boundary selectors are given, and the styles inside only apply between the two:
@scope (root) to (boundary)
Thus, you can scope styling to an overall tab component but not style the content embedded within. It is more of a target-restricting rule than a true change to the styling or inheritance of elements. Depending on how scopes nest, this yields a "closest scope wins" rule over same-specificity conflicts, since specificity remains a factor.
Stopping inheritance entirely remains in the more dramatic solutions: all: revert can reset all properties back to the browser default, and layer-specific version revert-layer could bounce a rule back to the project's own default later rather than using browser defaults. A harder line, though, is still the domain of shadow DOM's isolation; scope tries to be a purely CSS-dependent way to manage overlapping contexts without hard boundaries in the DOM.
Of the three features, cascade layers are closest to shipping as a "candidate recommendation." Container queries are next in line with issues around edge cases and looping, and scope remains the furthest out with an early proposal and much discussion needed.
Speaker Notes and Bonus Material
The role those drafts play is inherently overlapping. Layers tame cascade reliability; scope does as well — the specifics differ, but both address the same needs of authorship. Getting a working prototype running in Chrome Canary accelerates feedback. The historically fascinating process, much like the inner workings of the Selectors module, has shown how each incremental feature relies on prior "half steps" in the spec web, each adding a capability floor for the next. The browser ecosystem's designers are paying increasingly close attention to failure cases and how content and container constraints interlock.



