Should We Even Have :closed?
Publikováno: 20.11.2025
Is there really a difference between using :not(:open) and :closed? As always, it depends. Sunkanmi Fafowora explains why :closed is currently not a thing.
Should We Even Have :closed? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.
For the past few months, I’ve been writing a lot of entries on pseudo-selectors in CSS, like ::picker() or ::checkmark. And, in the process, I noticed I tend to use the :open pseudo-selector a lot in my examples — and in my work in general.
Borrowing words from the fine author of the :open entry in the Almanac:
The CSS
:openpseudo-selector targets elements that support open and closed states — such as the<details>and<select>elements — and selects them in their open state.
So, given this:
details:open {
background: lightblue;
color: darkred;
}We expect that the <details> element gets a light blue background and dark red text when it is in an open state (everywhere but Safari at the time I’m writing this):
But what if we want to select the “closed” state instead? That’s what we have the:closed pseudo-class for, right? It’s supposed to match an element’s closed state. I say, supposed because it’s not specced yet.
But does it need to be specced at all? I only ask because we can still target an element’s closed state without it using :not():
/* When details is _not_ open, but closed */
details:not(:open) {
/* ... */
}So, again: do we really need a :closed pseudo-class? The answer may surprise you! (Just kidding, this isn’t that sort of article…)
Some background
Talks surrounding :open started in May 2022 when Mason Freed raised the issue of adding :open (which was also considered being named :top-layer at the time) to target elements in the top layer (like popups):
Today, the OpenUI WC similarly resolved to add a :top-layer pseudo class that should apply to (at least) elements using the Popup API which are currently in the top layer. The intention for the naming and behavior, though, was that this pseudo class should also be general purpose. It should match any type of element in the top layer, including modal <dialog>, fullscreen elements, and ::backdrop pseudo elements.
This sparked discourse on whether the name of the pseudo-element targeting the top layer of any type of element (e.g., popups, pickers, etc.) should either be :open or :top-layer. I, for one, was thrilled when the CSSWG eventually decided on :open in August 2022. The name makes a lot more sense to me because “open” assumes something in the top layer.
To :close or :not(:open)?
Hold on, though! In September that same year, Mason asked whether or not we should have something like a :closed pseudo-class to accompany :open. That way, we can match elements in their “closed” states just as we can their “open” states. That makes a lot of sense, t least on the surface. Tab Atkins chimed in:
I love this definition, as I think it captures a concept of “openness” that lines up with what most developers think “open” means. I also think it makes it relatively straightforward for HTML to connect it to specific elements.
What do folks think?
Should we also talk about adding the corresponding
:closedpseudo class? That would avoid the problem that:not(:open)can match anything, including things that don’t open or close.
And guess what? Everyone seemed to agree. Why? Because it made sense at the time. I mean, since we have a pseudo-class that targets elements in their :open state, surely it makes sense to have :closed to target elements in their closed states, right? Right??
No. There’s actually an issue with that line of reasoning. Joey Arhar made a comment about it in October that same year:
I opened a new issue about
:closedbecause this doesn’t have consensus yet (#11039).
Wait, what happened to consensus? It’s the same question I raised at the top of this post. According to Luke Warlow:
Making
:closedmatch things that can never be open feels odd. And would essentially make it:not(:open)in which case do we even need:closed? Like we don’t have a:popover-closedbecause it’s the inverse of:popover-open.
There is no :closed… for now
Fast forward one more month to November 2024. A consensus was made to start out with just :open and remove :closed for the time being.
Dang. Nevertheless, according to WHATWG and CSSWG, that decision could change in the future. In fact, Bramus dropped a useful note in there just a month before WHATWG made the decision:
Just dropping this as an FYI: :read-only is defined as :not(:read-write), and that shipped.
Which do you find easier to understand?
Personally, I’m okay with :closed — or even using :not(:open) — so far as it works. In fact, I went ahead swapped :closed for :not(:open) in my ::checkmark and ::picker() examples. That’s why they are they way they are today.
But! If you were to ask me which one comes easier to me on a typical day, I think I would say :closed. It’s easier for to think in literal terms than negated statements.
What do you think, though? Would you prefer having :closed or just leaving it as :not(:open)?
If you’re like me and you love following discussions like this, you can always head over to CSSWG drafts on GitHub to watch or participate in the fun.
Should We Even Have :closed? originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.