Chris’ Corner: Layers of Layers
There’s this thing that you need to know about when dealing with z-index and trying to get some elements to be on top of other elements: stacking contexts. If you’ve got an element within a stacking context that is itself lower than another element that you’re trying to get on top of, well, you’re hosed.
And yet, these days, there is something of an escape hatch. Stephanie Eckles introduces our hero:
A modern web feature is the “top layer,” which is guaranteed to be the top-most layer above any other stacking context. It spans the entire viewport, although elements existing in the top layer may have smaller visible dimensions.
If you can get an element onto the top layer, it just will be on top of everything else. Stacking contexts be damn. Open dialogs and popovers will be on the top layer automatically.
And yet.
This combination of dialog and popover can potentially lead to other stacking problems where a visual popover might still be rendered inaccessible by a dialog. This is the whole thing Stephanie is talking about.
When the native HTML dialog is launched via showModal(), the page outside of the dialog becomes inert. The state of inert is a necessary accessibility behavior, which results in isolating the dialog contents, and prevents both tab and virtual cursor access to the background page.
A popover is part of the background page, so even if you can see it, when a modal is open, it’s inert. Weird. Quite the gotcha.
Speaking of the top layer, I finished up a three-part series call In-N-Out Animations (starting here) that goes all into animating dialogs and popover both on the way in and on the way out.
Don’t confuse the “top layer” with @layer in CSS. Different concepts. Using @layer in CSS allows you to make whole chunks of CSS apply as more-strong or less-strong than other chunks of CSS. Beating even specificity, which just feels extra weird. I’d tell you it’s kinda like z-index for actual CSS code but, uhm, that’s going to confuse you so pretend I didn’t say that.
Imagine you have:
<div class=”el” id=”el”></div>
Certainly a #el selector is going to beat a .el selector, because that’s just how CSS specificity works. But if we layer it, we can make the class selector win instead.
@layer my-layer-one, my-layer-two;
@layer my-layer-one {
#el {
background: red;
}
}
@layer my-layer-two {
.el {
background: green;
}
}
Sprinkling on another little bit of knowledge, styles that aren’t in any layer are stronger than any layered style. So if you want to lower the strength of a particular chunk of CSS, just layer it. Manuel Matuzo shared this idea, as an alternative to the :where() trick you see sometimes.
Layering CSS is kind of a big choice. It generally makes more sense to me as something you’d do from the outset of a project. But most of us aren’t working on brand new CSS architectures every day. Is it possible to sprinkle in layers when useful? It clearly was for Manuel, and honestly, we do it here at CodePen in an interesting way I’ll have to share sometime. But also, Victor Ayomipo has some thoughts in Integrating CSS Cascade Layers To An Existing Project. A good start is probably that Your CSS reset should be layered.
Karl Koch has a nice article On clip-path animations. The idea is this + button in a corner of a card that, when clicked open, expands into a details area. But the expansion happens by a growing expansion of a clipped circle, which leads to a nice effect.
I gotta imagine the new border-shape is going to lead to some super sweet animation potential as well.
I think it’s hilarious that Temani put together, literally, one hundred CSS declarations that center an element inside a container.



