Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it ok for popover to claim general names like :open and :closed? #9055

Closed
jakearchibald opened this issue Mar 21, 2023 · 25 comments
Closed
Labels
topic: popover The popover attribute and friends

Comments

@jakearchibald
Copy link
Contributor

https://html.spec.whatwg.org/multipage/semantics-other.html#pseudo-classes:popover-showing-state

Right now, popovers get a pseudo-class of :open when they're open, and :closed when they're closed.

These seem like really general names. Does it make sense for popover to own them?

Without understanding this is purely a popover feature, it seems weird that el.matches(':open') doesn't apply to open <details>, <dialog>, <select>, etc etc.

@jakearchibald jakearchibald added the topic: popover The popover attribute and friends label Mar 21, 2023
@jakearchibald jakearchibald changed the title Is it ok for popover to claim a general name like :open and :closed? Is it ok for popover to claim general names like :open and :closed? Mar 21, 2023
@jakearchibald
Copy link
Contributor Author

It seems like this issue has been noticed when it comes to the script APIs, which are named openPopover() rather than just open() (since the methods appear on HTMLElement, it isn't a popover-specific namespace). It feels the CSS API should be similarly namespaced, if the terms are to be popover specific.

:popover-open and :popover-closed seem like natural choices, but maybe there are better choices.

@jakearchibald
Copy link
Contributor Author

jakearchibald commented Mar 21, 2023

From https://drafts.csswg.org/selectors/#open-state

The :open pseudo-class represents an element that has both “open” and “closed” states, and which is currently in the “open” state.

Exactly what “open” and “closed” mean is host-language specific, but exemplified by elements such as HTML’s details, select, and dialog elements, all of which can be toggled “open” to display more content (or any content at all, in the case of dialog).

From https://html.spec.whatwg.org/multipage/semantics-other.html#selector-open

The :open pseudo-class is defined to match any HTML element whose popover attribute is not in the no popover state and whose popover visibility state is showing.

So there's disagreement here between the specs. The CSS spec thinks it should apply to other elements, the HTML spec thinks otherwise (and seems against the resolution - thanks @bkardell for the heads-up).

The issue is, we'll quickly end up with code written assuming that document.querySelectorAll(':open') will match open popovers, and later including <details> will be a compat issue.

But let's say we do things the CSS spec way. What does details:open mean? I guess it means the details is showing its content, or that the details is also a popover that's 'showing', or both 🤷

@keithamus
Copy link
Contributor

relates to #8625

@jakearchibald
Copy link
Contributor Author

Also #8884

@nt1m
Copy link
Member

nt1m commented Mar 21, 2023

I kind of like :open / :closed for developer ergonomics, but it'd be unfortunate to prefix with popover just because of the conflict. No strong opinion here though.

@annevk
Copy link
Member

annevk commented Mar 21, 2023

I don't think there is disagreement with the CSS WG. It just hasn't been implemented for all features as-of-yet as the issues above show. Popovers happened to be first.

@jakearchibald
Copy link
Contributor Author

There's no concern around dialog:open, which can be open in two different ways, potentially at the same time?

@annevk
Copy link
Member

annevk commented Mar 22, 2023

I don't know. Is it likely web developers would run into it? Or are you concerned about generic code not being able to distinguish?

@nt1m
Copy link
Member

nt1m commented Mar 22, 2023

Dialog can't be [open] and a popover at the same time, they're one or the other, the "check popover validity" algorithm & the dialog.show/showModal() algorithms enforce this.

I could see the confusion if we expand the definition to things like <details> though.

@nt1m
Copy link
Member

nt1m commented Mar 22, 2023

Though it's unlikely that web developers are going to use expandable widgets like <details> or <select> as popovers tbh, if this is something we are concerned about, I'd rather forbid using those as popovers.

@jakearchibald
Copy link
Contributor Author

I could see the confusion if we expand the definition to things like <details> though

Hah, yeah, I meant to type details:open.

I guess I'm a little nervous about "it probably won't happen much" being the reasoning, when we should just prevent it being a problem.

@annevk
Copy link
Member

annevk commented Mar 22, 2023

Pseudo-classes kinda have this generic nature to them though. E.g., :default ends up matching a bunch of unrelated things as well. Perhaps the feedback is that the CSS WG shouldn't be introducing pseudo-classes that are generic?

@jakearchibald
Copy link
Contributor Author

I think the difference here is that there's overlap with the various definitions of open. With :default, it seems like you can determine the type of default by the tag name. input:default and button:default have pretty different definitions, but in those selectors you're only using one of those definitions (although maybe different pseudo classes would have been clearer).

Whereas:

  • dialog:open can mean one of two things (but maybe they're similar enough that it's ok? Or maybe that's worse?)
  • details:open and select:open can mean one of two pretty different things, or even both at the same time.

This gets even trickier when you consider :closed:

The :closed pseudo-class represents an element that has both “open” and “closed” states, and which is currently in the closed state.

If we take that as written, then it means <details popover> can be :open and :closed at the same time. As in, it's :open in the popover definition, but also :closed in the details definition. Same applies to <select popover>.

The definition could be changed to:

The :closed pseudo-class represents an element that has both “open” and “closed” states, and which is not in the open state.

…which avoids the both-states-at-once problem, but it also means <details popover> would not be :closed when it's an open popover, even though it's closed in terms of details.

@annevk
Copy link
Member

annevk commented Mar 22, 2023

@jakearchibald note that <input> can represent a submit button and thus match :default for that reason as well.

@whatwg/css should probably weigh in here.

@brechtDR
Copy link

I believe clear language is important. So i'm still in favour of simple terms such as open and closed. The most basic reason: easier to learn and understand. Especially if there would be a prefix for everything in the future, i believe that it would become too confusing, consistency is key.

But I won't downplay the concerns here as there are some really interesting cases here.

@jakearchibald
Copy link
Contributor Author

So i'm still in favour of simple terms such as open and closed.

I don't think number of characters is a fair measure of simplicity. The term may be simple, but the behaviour isn't.

The most basic reason: easier to learn and understand. Especially if there would be a prefix for everything in the future, i believe that it would become too confusing, consistency is key.

Consistent with what? This kinda reminds me of the Monty Python sketch, abridged somewhat:

Second Bruce: G'day, Bruce!
First Bruce: Oh, Hello Bruce!
Third Bruce: How are you Bruce?
First Bruce: A bit crook, Bruce.
Second Bruce: Where's Bruce?
First Bruce: He's not 'ere, Bruce.
Fourth Bruce: Gentleman, I'd like to introduce you to Michael.
First Bruce: Is your name not Bruce?
Michael: No, it's Michael.
Second Bruce: That's going to cause a little confusion.
Third Bruce: Mind if we call you 'Bruce' to keep it clear?

…where everyone having the same name is confusing, but it's done in the name of consistency.

Calling many different behaviours "open" and "closed" isn't making things simpler, it's making things more complicated, especially in cases where a single element can use different definitions of "open" and "closed", and use multiple of those at the same time.

@jakearchibald
Copy link
Contributor Author

Summary for the call:

Right now, :open and :closed only apply to popovers. From https://html.spec.whatwg.org/multipage/semantics-other.html#selector-open

The :open pseudo-class is defined to match any HTML element whose popover attribute is not in the no popover state and whose popover visibility state is showing.

Although, it seems like there might be appetite to expand this to other elements later #8884. And that seems to match the original intent and resolution.

From https://drafts.csswg.org/selectors/#open-state:

The :open pseudo-class represents an element that has both “open” and “closed” states, and which is currently in the “open” state.

Exactly what “open” and “closed” mean is host-language specific, but exemplified by elements such as HTML’s details, select, and dialog elements, all of which can be toggled “open” to display more content (or any content at all, in the case of dialog).

There's some risk to doing this later, as code in the wild like el.matches(':open'), which currently can only match open popovers, would suddenly start matching other elements.

But even if that change can be made, it seems bad to have overlap with the various definitions of open. With say, :default, you can limit the definition you use via the selector: input[type=radio]:default and button:default have pretty different definitions, but in those selectors you're only using one of those definitions (although maybe different pseudo classes would have been clearer).

Whereas:

  • dialog:open can mean one of two things (but maybe they're similar enough that it's ok? Or maybe that's worse?)
  • details:open and select:open can mean one of two pretty different things, or even both at the same time.

This gets even trickier when you consider :closed:

The :closed pseudo-class represents an element that has both “open” and “closed” states, and which is currently in the closed state.

If we take that as written, then it means <details popover> can be :open and :closed at the same time. As in, it's :open in the popover definition, but also :closed in the details definition. Same applies to <select popover>.

The definition could be changed to:

The :closed pseudo-class represents an element that has both “open” and “closed” states, and which is not in the open state.

…which avoids the both-states-at-once problem, but it also means <details popover> would not be :closed when it's an open popover, even though it's closed in terms of details.

I think this would be much clearer if the overlap was avoided. If we want pseudo-classes for open popovers (I guess there's a question if we need them at all), we could have a pseudo-class targeting that specifically, such as :popover-open.

@zcorpan
Copy link
Member

zcorpan commented Mar 23, 2023

Would the problem go away if we prevent details and select from being popovers?

@zcorpan
Copy link
Member

zcorpan commented Mar 23, 2023

dialog:open can mean one of two things (but maybe they're similar enough that it's ok? Or maybe that's worse?)

Do you mean it can be open as non-modal and open as modal? Since :modal exists, that seems fine to me.

@jakearchibald
Copy link
Contributor Author

jakearchibald commented Mar 23, 2023

Would the problem go away if we prevent details and select from being popovers?

It solves the overlap on those elements. We'd also need to prevent popover applying to anything else that could be open/closed in future. That would probably prevent any other attribute adding open/closed behaviour too (in the way popover does).

Do you mean it can be open as non-modal and open as modal? Since :modal exists, that seems fine to me.

Dialogs can be open non-modal, open modal, open as a popover, or none of those. The :closed state is still tricky.

@zcorpan
Copy link
Member

zcorpan commented Mar 23, 2023

Ah, I misunderstood and thought dialog was disallowed from being a popover always. But yeah, it seems to me the non-confusing options are:

  • prevent all elements with their own open/closed state from being popovers, or
  • make popover's open/closed pseudo-classes only apply to popover (and maybe avoid generic names)

@brechtDR
Copy link

Calling many different behaviours "open" and "closed" isn't making things simpler, it's making things more complicated

I somehow agree, but just saying we shouldn't rush to conclusions.
What i ment is that we should avoid going into a future where your CSS would look like the following:

.some-popup:popoveropen {
/*popover styles open here */
}

.somethingelse:somethingelseopen {
/* the other thing */
}

So yes, personally, i'm not a fan of the prefixed idea. -> What i ment with consistency.

@zcorpan seems to be the interesting way to go about this instead of longer/prefixed names.

@jakearchibald
Copy link
Contributor Author

Open UI resolution: Talk to CSSWG about specific pseudo-class instead of :open, such as :popover (similar to :fullscreen)

Minutes: https://www.w3.org/2023/03/23-openui-minutes.html#t05

@mfreed7
Copy link
Contributor

mfreed7 commented Mar 23, 2023

I opened a CSSWG issue to discuss: w3c/csswg-drafts#8637

@domenic
Copy link
Member

domenic commented Apr 6, 2023

I think this was fixed by #9077; please let me know and/or reopen if I'm wrong.

@domenic domenic closed this as completed Apr 6, 2023
luwes added a commit to luwes/selectlist-polyfill that referenced this issue Jun 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: popover The popover attribute and friends
Development

No branches or pull requests

8 participants