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

Add the :open pseudo-class #10126

Merged
merged 17 commits into from
Dec 10, 2024
Merged

Add the :open pseudo-class #10126

merged 17 commits into from
Dec 10, 2024

Conversation

josepharhar
Copy link
Contributor

@josepharhar josepharhar commented Feb 7, 2024

This pseudo-class are defined in CSS here: https://drafts.csswg.org/selectors-4/#open-state

:open matches on details and dialog elements when they are open. :open matches on select and input elements if they are in a state which supports a picker popup and that picker popup is open.

(See WHATWG Working Mode: Changes for more details.)


/input.html ( diff )
/semantics-other.html ( diff )

source Outdated Show resolved Hide resolved
@josepharhar
Copy link
Contributor Author

@nt1m maybe you're interested in this?

Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling this!

source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
@domenic
Copy link
Member

domenic commented Feb 9, 2024

These match on details, dialog, and select elements since they can be in an open or closed state.

Has it been discussed whether they should match other pickers besides select, like color pickers, date pickers, etc.? Basically all the things that showPicker() triggers.

@josepharhar
Copy link
Contributor Author

Has it been discussed whether they should match other pickers besides select, like color pickers, date pickers, etc.? Basically all the things that showPicker() triggers.

That sounds great! I just used it on the elements that the css spec listed, but I don't see any reason why we shouldn't support <input> as well.

I think this might get nuanced even more than <select> since some browsers have popups for date/time input types and others don't. How should I proceed?

@annevk
Copy link
Member

annevk commented Feb 10, 2024

I wonder if we can turn "If no such UI applies to element" into a rendering concept and branch :open/:closed on that. That would also allow you to detect picker support. This should not introduce a new fingerprinting vector as it will be 1:1 with the user agent.

cc @nt1m @pxlcoder @lukewarlow

@lukewarlow
Copy link
Member

As far as I understand the reason showPicker() doesn't return a success boolean was because browsers explicitly didn't want to "leak" the information about whether they show a picker on these elements, I think it was for forwards compatability so they'd be free to add them in future without people relying too much on them existing or not in a given UA.

I personally think it would be great if we could apply these to those elements and support the feature detection for showPicker().

source Outdated Show resolved Hide resolved
@annevk
Copy link
Member

annevk commented Feb 19, 2024

If it was decided that showPicker() shouldn't reveal that information we should not make :open and :closed applicable to those elements until we decide otherwise. It seems reasonable to explore further as a follow-up though.

@josepharhar
Copy link
Contributor Author

As far as I understand the reason showPicker() doesn't return a success boolean was because browsers explicitly didn't want to "leak" the information about whether they show a picker on these elements

I'd be interested to hear more about this, is there a conversation you can point to?

@lukewarlow
Copy link
Member

I'd be interested to hear more about this, is there a conversation you can point to?

Absolutely, so there's an open issue regarding lack of feature detection for showPicker() here and that links to a TAG design review comment here

It seems the lack of support detection was the hang up that lead to an unsatisfied resolution in TAG.

My earlier remark that "browsers" didn't want to leak might be a mischaracterisation upon further reading. But the sentiment is the same, it was concluded that it was an undesirable compat trade off.

@josepharhar
Copy link
Contributor Author

Absolutely, so there's an open issue regarding lack of feature detection for showPicker() #7790 and that links to a TAG design review comment w3ctag/design-reviews#688 (comment)

Thanks! @domenic do you think these issues still apply with this pseudo class?

@domenic
Copy link
Member

domenic commented Feb 22, 2024

Thanks! @domenic do you think these issues still apply with this pseudo class?

It depends exactly how they're defined. Consider a case like <input type=password> where browser A shows a picker and browser B does not show a picker. If we define this as matching :closed in browser B, then the issues do not occur: the web developer cannot write code that works differently in browser A vs. B. Whereas if we say that neither :open nor :closed match in browser B, then the web developer can easily write code that works differently in the two browsers, e.g. they might give only the correct styling to browser A because they put the correct styling in #my-input:closed { ... }.

Similarly, if we go with the "neither :open or :closed matches no-picker controls" model, then browser B adding picker support in one release would potentially cause new styles to apply, which is a compat risk for browser B.

That said, I don't feel that the interop and compat issues with revealing the picker-UI-or-not status of a control are blocking. I think they're reason to be cautious, but if all the implementers in the room are willing to eat those interop and future-compat costs, then from a HTML editor perspective, I have no objection.

@annevk
Copy link
Member

annevk commented Mar 4, 2024

I suppose that essentially argues for making :closed match all elements, or at least all elements that might have a picker UI. @whatwg/css does that seem reasonable?

@lukewarlow
Copy link
Member

Following up on this another place where we'd potentially like to do something that exposes picker UI existence is with invokers. If we were to add showPicker actions to invokers then it would seem logical (though I'm no expert so this might be wrong) that it exposes an aria-expanded state based on the inputs picker state?

If aria-expanded should be added it would be unfortunate if we couldn't because of this compat risk (though admittedly it's not currently detectable in code so maybe it's fine?)

@lukewarlow
Copy link
Member

Something I've just thought of. Would it be worth exposing this on datalist elements? They're kind of input pickers but also they're a separate element so idk if input:open matching necessarily makes sense for a datalist?

@josepharhar
Copy link
Contributor Author

Something I've just thought of. Would it be worth exposing this on datalist elements? They're kind of input pickers but also they're a separate element so idk if input:open matching necessarily makes sense for a datalist?

I feel like input:open makes more sense than datalist:open since we are planning on doing select:open rather than select::picker(select):open

@lukewarlow
Copy link
Member

@josepharhar
Copy link
Contributor Author

I suppose that essentially argues for making :closed match all elements, or at least all elements that might have a picker UI. @whatwg/css does that seem reasonable?

I think that making :closed match "all elements" makes sense based on domenic's explanation for compat. I added another line for input elements and said that they should always match either open or closed. I also made all select elements match either open or closed regardless of whether they have list-box rendering or not.

@lukewarlow
Copy link
Member

Is one possibility to ship :open and not :closed initially? Making :closed match 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-closed because it's the inverse of :popover-open.

Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Luke that starting out with just :open is better, but we should run that by the CSS WG.

source Outdated Show resolved Hide resolved
@bramus
Copy link

bramus commented Oct 11, 2024

Is one possibility to ship :open and not :closed initially? Making :closed match 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-closed because it's the inverse of :popover-open.

Just dropping this as an FYI: :read-only is defined as :not(:read-write), and that shipped – https://html.spec.whatwg.org/multipage/semantics-other.html#selector-read-only.

@josepharhar josepharhar changed the title Add the :open and :closed pseudo-selectors Add the :open pseudo-class Nov 26, 2024
@josepharhar
Copy link
Contributor Author

:closed was resolved to be removed for now, so I'm removing it from this PR: w3c/csswg-drafts#11039 (comment)

source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
Copy link
Member

@annevk annevk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@josepharhar thanks so much, I pushed some nits and this looks good to me now. Can you fill out the PR template?

@domenic @zcorpan last chance for nits bell.

@lukewarlow
Copy link
Member

Just dropping this as an FYI: :read-only is defined as :not(:read-write)

Isn't that from before the :not() selector though?

Either way I think dropping closed for now is better than defining it as :not(:open) in case we want to define it properly in future where it's not equivalent.

source Show resolved Hide resolved
source Show resolved Hide resolved
source Show resolved Hide resolved
source Outdated Show resolved Hide resolved
source Show resolved Hide resolved
source Show resolved Hide resolved
@domenic domenic added addition/proposal New features or enhancements topic: forms topic: style topic: dialog The <dialog> element topic: select The <select> element labels Dec 10, 2024
@domenic domenic merged commit efce764 into whatwg:main Dec 10, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements topic: dialog The <dialog> element topic: forms topic: select The <select> element topic: style
Development

Successfully merging this pull request may close these issues.

6 participants