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

[selectors-4] Introduce :popovertarget-open pseudo class #9547

Open
ggedde opened this issue Nov 1, 2023 · 13 comments
Open

[selectors-4] Introduce :popovertarget-open pseudo class #9547

ggedde opened this issue Nov 1, 2023 · 13 comments
Labels
selectors-4 Current Work

Comments

@ggedde
Copy link

ggedde commented Nov 1, 2023

Looks like :popover-open is landing, but it only applies to the popover element itself.
We also need a way to style the Trigger element for the popover element when the popover element is open.

consider the following:

<button popovertarget="my-popover">Open Popover</button>
...
<div popover id="my-popover">Greetings, one and all!</div>

I would like a way to style the button when the popover is open.
This would need to apply to all elements that have the same 'popovertarget'
Ex.

<button popovertarget="my-popover">Open Popover</button>
...
<div popover id="my-popover">Greetings, one and all!</div>
...
<button popovertarget="my-popover">Open Popover From another button</button>

It would be ideal to have something like:

button:popovertarget-open {
   ...
}

Thanks

@ggedde ggedde changed the title [selectors-4] Introduce :popover-target-open pseudo class [selectors-4] Introduce :popovertarget-open pseudo class Nov 1, 2023
@YummyBacon5
Copy link

YummyBacon5 commented Nov 1, 2023

Just to note: popovertarget is being planned to be replaced with invoketarget by the Open UI CG. (explainer)

Meaning that the selector name would be different. And that other invokeactions could be included. As well as interesttarget

@ggedde
Copy link
Author

ggedde commented Nov 1, 2023

Looks like the explainer for invoketarget might use aria-expanded=true when opened and aria-expanded=false when closed which is good. As long as it works on all invokees and not just the last one used, etc.

@YummyBacon5
Copy link

YummyBacon5 commented Nov 1, 2023

It would in the accessibility API. But this wouldn't be an attribute which could be selected with CSS. So a new pseudo-class selector for this would still be needed

@nt1m
Copy link
Member

nt1m commented Nov 3, 2023

cc @keithamus if you have ideas of what can be done here.

I would think :has(:popover-open) + a certain DOM structure makes this possible. Having something more generic for invokers would require a precise definition.

@ggedde
Copy link
Author

ggedde commented Nov 3, 2023

@YummyBacon5 It would in the accessibility API. But this wouldn't be an attribute which could be selected with CSS. So a new pseudo-class selector for this would still be needed

I am not that familiar with the accessibility API, but if aria-pressed is updated then we can access that with CSS. Do you have any links or information showing this in the accessibility API?
Thanks

@ggedde
Copy link
Author

ggedde commented Nov 3, 2023

cc @keithamus if you have ideas of what can be done here.

@nt1m I would think :has(:popover-open) + a certain DOM structure makes this possible. Having something more generic for invokers would require a precise definition.

We shouldn't have to rely on adding the elements next to each other or in a specific container, etc. The power of the popover api allows us to have the elements separate from each other. At which point we would need a way to know if the invokers target has been changed. As far as a precise definition as long as they contain popovertarget then we can determine if the target is open then add a pseudo class to the invoker. Essentially, whenever a target has changed the browser should fine ALL invokers and add a pseudo class to them as well.
Thoughts?

@nt1m
Copy link
Member

nt1m commented Nov 3, 2023

With the invokers proposal, I wonder if we should have a :invoketarget() function that takes a selector to match against.

button:invoketarget(:popover-open) would match a button whose invoketarget matches :popover-open.

Implementing invalidation for something like this would probably involved though (imagine all the combinations like :invoketarget(:has(...))!)

@YummyBacon5
Copy link

YummyBacon5 commented Nov 3, 2023

I am not that familiar with the accessibility API, but if aria-pressed is updated then we can access that with CSS. Do you have any links or information showing this in the accessibility API?

Every HTML element is internally mapped to ARIA role and state(s). Where these properties are then communicated to assistive technologies through an accessibility API.

But basically, the actual ARIA attributes are not going to be added to the elements, and are just represented internally. So a CSS selector can't select them.


button:invoketarget(:popover-open) would match a button whose invoketarget matches :popover-open.

This was also kinda suggested by @lukewarlow in openui/open-ui#898 (comment)

@lukewarlow
Copy link
Member

lukewarlow commented Nov 3, 2023

Hmm @nt1m your function selector is probably a much better idea than my pseudo element one (especially because pseudo elements don't currently work in :has()).

I do feel like some way to select in css is needed though. Because it's common for playpause buttons for example to change their appearance based on state and that would currently rely on a specific Dom structure and has().

But as you say it would be quite picky with regards to invalidation.

Could we potentially flip the idea (both would select the invoker button)?

#popover:popover-open:invoker() or #popover:popover-open::invoker

Would this simplify things?

@keithamus
Copy link
Member

Perhaps a more generic selector which applies when an element that is tied to another open element is expanded - effectively providing a styling hook for the implicit aria-expanded state. Let's say :expanded. This would apply to the button that expanded an element, and would be applied to buttons with a popovertarget that points to an open popover, or a invoketarget that points to an open popover, open dialog, or open details element. It could also apply to Summary elements that have open details (so effectively summary:expanded and details[open] > summary would be the same thing), and would be helpful for the new <selectlist> and <combobox> elements.

@YummyBacon5
Copy link

Perhaps a more generic selector which applies when an element that is tied to another open element is expanded - effectively providing a styling hook for the implicit aria-expanded state

This would be confusing for the video pause/play icon use case. Since saying that a button for a video is "expanded" just because the video is playing is confusing.

Also I don't think that this would work with custom invoker actions - where there's no true/false state.

@lukewarlow
Copy link
Member

Yeah that would only be doable for the popover, dialog, details scenario
. Not all invokers, which perhaps is fine? Maybe it's something worth thinking on separately from a more general invokers specific one?

@keithamus
Copy link
Member

keithamus commented Nov 3, 2023

Perhaps a more generic selector which applies when an element that is tied to another open element is expanded - effectively providing a styling hook for the implicit aria-expanded state

This would be confusing for the video pause/play icon use case. Since saying that a button for a video is "expanded" just because the video is playing is confusing.

Also I don't think that this would work with custom invoker actions - where there's no true/false state.

Both of these are correct and intentional.

  • Invokers won't set aria-expanded for buttons like video pause/play, only the afforementioned details,dialog,popover would get that. Instead it would likely be aria-pressed. We could have another pseudo class for this case but I'm not fully convinced there's a use case that differentiates from other states like :active.
  • We cannot determine if custom invoker actions influence thearia-pressed or aria-expanded state, and so in these cases the very likely outcome is that browsers won't expose any implicit aria information as a consequence of invoking a custom invoker action. Consequently your application scripting would need to deal with this, which likely means setAttribute('aria-pressed') or setAtrribute('aria-expanded'). In those cases the attributes become easy to select for, meaning that a selector for button:is(:expanded, [aria-expaned="true"]) would cover all expanded cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
selectors-4 Current Work
Projects
None yet
Development

No branches or pull requests

6 participants