“Regardless of where it is in the DOM.”
That’s a phrase that goes through my mind in regard to a number of new CSS features and it’s so cool. I certainly spent most of my formative HTML & CSSin’ years being very careful about where things needed to go in the DOM specifically because CSS needed them to be there. It’s still important to care about DOM structure, putting things where they should be for accessibility reasons, but it’s nice that we don’t have to structure things according to limitations of the styling language so much anymore.
A big one here is :has()
.
Think of this:
body:has(input[type="checkbox"][switch]:checked) .menu {
}
Perhaps that toggle switch opens a menu. I don’t have to care where the toggle switch is in the DOM and I don’t have to care where .menu
is in the DOM. Neither. That will still work. Wow. If we wanted to pull off trickery like this in the past, we’d have to rely on combinators in CSS like ~
and +
, which meant that the elements needed to be siblings of one another which is pretty constraining tbqh. Here’s Amit pairing this stuff with a <select>
menu with some awfully practical results.
Another huge one is the <dialog>
element and super best friend <div popover id="popover">
. In the past we’d almost certainly put elements like this that need to be “top level” to guarantee visibility as children of the <body>
. That way there was no chance some weird positioning context would limit their ability to have a high z-index
and definitely be seen above all other elements. Now, it just doesn’t matter. These elements are automatically promoted to the “top layer” (beating any sort of z-index
shenanigans) no matter where they are in the DOM. That’s excellent, as sometimes it just makes sense for these elements to be contextually next to other things. Particularly for popovers, which are likely providing more context for content that is intentionally limited by default.
Then we’ve got anchor positioning, which doesn’t yet have as much support as the other features here, but shares the DOM position irrelevance benefit.
.anchor {
anchor-name: --my-anchor;
}
.target {
position: absolute;
position-anchor: --my-anchor;
}
These two elements can be entirely wherever in the DOM. The best we could do in the past in situations like this is to make the target a child of the anchor and use absolute positioning inside the relative positioning context. It was limiting and annoying.
I’ve enjoyed reading Eric Meyer’s explorations like An Anchored Navbar Solution and Nuclear Anchored Sidenotes which feel pretty real-world-y, both use anchor positioning, and evaluate the tradeoffs.
Ya know I kinda lost the plot on anchor positioning for a minute there though. Part of what I liked about Eric’s sidenotes concept is that they anchored based on two different elements. As in they were vertically positioned at the same level as some arbitrary text element in a blog post, and the were horizontally positioned off to the side of the blog post based the article element around the entire blog post. That seemed clever and useful.
Here’s a more convoluted demo:
Apparently this is kind of the “old” way though. Here’s a nice primer post on all this: Let’s hang! An intro to CSS Anchor Positioning with basic examples. And it says:
There are currently two major ways how you can get anchoring to happen. Without going too much into the history, this is the short version of why that is: There was an experimental implementation with the
anchor()
function and@position-fallback
(not position-try, we’ll get there) when a new idea was launched by Webkit with an alternative solution using more of a grid-like system.
So I don’t really get if anchor()
is deprecated or what. I do agree though that the position-area
property is really simple and clear on placing an anchored element somewhere though. I’m not going to get into all the “fallbacks” stuff with this, but suffice it to say it’s all powerful, cool, and interesting, while certainly taking a while to wrap your mind around. I see CSS-Tricks is very on the job.
I’ll say I’m not particularly worried about performance on any of this stuff. Maybe I should be, I dunno. Calculating position does tend to be one of those things that can be costly. I just read a post about how mask-position
was a culprit for pretty dramatic slowdowns on a particular design. Mostly I trust that CSS implementations are just better now?