Is :open the same as :popover-open?


Obviously, the answer is no. But, the next question you’d ask is how? In the MDN documentation, we clearly have :open being defined as “The :open CSS pseudo-class represents an element that has open and closed states, only when it is currently in the open state.*”*
And then you also have, the CSS :popover-open
which has a similar definition that says, “The :popover-open CSS pseudo-class represents a popover element (i.e., one with a popover attribute) that is in the showing state*. You can use this to apply style to popover elements only when they are shown.*”
I know it’s really a play with semantics, but this got confusing because the <details>
element and the <dialog>
element have this “open” or “showing” state, so what does it really mean?
When I saw the CSS :open
pseudo-class getting support from Intent to Ship, I was rather intrigued, so I decided to investigate what exactly this pseudo-class does.
:open
basically allows you to style HTML elements like <dialog>
, and <details>
when they are in their “open state” (the element is showing on the screen and it is NOT hidden, as hidden was its default state).
It also styles the HTML <select>
and color input in the HTML <input>
tag when they have a picker showing on the web page (e.g <input type="color"/>
). This “open state” simply means the state whereby the tag is expanded or a dropdown is shown to the user. In essence, a certain display is shown from its default hidden state.
I then asked, doesn’t CSS :popover-open
do the same thing? Yes, but no. Let me explain.
How does :popover-open work?
The CSS :popover-open
pseudo-element applies to HTML elements with the popover attribute. Without this attribute, the style is not applied.
Now, the popover is in its “open state” that only applies to elements that have been marked with the popover attribute. Let’s say we want to apply this popover attribute with the :open pseudo class. I mean, there is a display showing, right? Right?? No, even the demo below won’t work even if I apply use the :open
pseudo-class on the popover element because well, it’s not part of the accepted HTML elements (i.e it doesn’t have an open and closed state, which the documentation clearly states).
But, what if I use <details>
instead with the popover attribute?
According to the official documentation, :open and :popover-open are different in the sense that “…an element can have element-specific open and closed states and also have separate popover-showing and popover-hidden states associated with being a popover.”
This means that you can have an HTML element like <details>
and still have a popover inside of it. However, accessing the two in one element when the element does not have an open and closed state, as I did above, will not work.
To combine the two, you just need to keep the attributes in different HTML elements or use them in a nested format, which I will show below.
Here’s another obscure example:
Imagine a <details>
element, which can either be open or closed. CSS allows us to target it when it’s open:
details {
background: white;
&:open {
background: green;
}
}
But, a <details>
element can also be a popover! That’s weird, but it’s possible, so the web platform has to deal with it.
<details popover id=“my-details">
…
</details>
<button popovertarget=“my-details”>
Show
</button>
Now the <details>
element is entirely hidden by default. Not just its content closed, but the entire thing. Click that button, and it becomes visible. Now the details element itself can be interacted with and opened/closed itself. But that is different state from its popover state. So you can see how the web platform was forced into having differently named pseudo-classes here.
details {
background: white;
&:open {
background: green;
}
&:popover-open {
background: pink;
}
}
It seems likely that these states will be used for animation moreso than base styles.
Differences between :open
and :popover-open
Here’s a brief list of their differences in a table.
:open | :popover-open |
Applies to certain elements like <details>, <select> element with a dropdown display, some <input> elements like <input type="color"> that have show a display, | Only applies to popover elements that are shown or “popped out” on the screen. |
Uses the open attribute and this displays the hidden part of the HTML element | Uses the popover attribute in conjunction with popovertarget for this to work |
It’s not associated with any API, just native to HTML as an attribute and can be accessed with the pseudo-class :open | It’s associated with the Popover API |
CSS access for the attribute is with :open e.g <details>:open | CSS access for the attribute is with :popover-open |
Suppose there’s anything you would take from this article, it is that the main difference is, the :popover-open
applies to specific elements that have the popover attribute, and this can be any HTML element. But, the :open
pseudo-class only applies to elements such as <select>
, <details>
, etc.
They do have similarities, though, in that they are both powerful CSS pseudo-classes, and something (whether it's a dropdown or popover) is being shown.
Gosh! I had the documentation throwing around words like “open state” really confused me for some reason. It had me thinking they were the same thing, but they’re not! 😭
Hope this clears out any confusion if you come across this too! :)
Special shoutout to Chris Coyier for some edits in making this clearer!
Follow ME!
Thank you for reading up to this point. You’re a superstar! 🌟
If you enjoyed this article, make sure to give me a follow here (on hashnode) and my socials below for more info on future articles, guides, and CSS tips.
Subscribe to my newsletter
Read articles from Sunkanmi Fafowora directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Sunkanmi Fafowora
Sunkanmi Fafowora
Lover of all things tech. I write articles on Front-end development, JavaScript, React, Python, and anything that makes my life easier. Thanks for stopping by! 😊💛