Open mrego opened 3 years ago
Can you expand on why the host
element is matching :focus-visible
?
So this behavior was part of all the delegatesFocus
stuff (which I haven't followed that closely). Firefox doesn't implement it yet.
The general idea behind this behavior, IIRC, is that it's a bit weird that .activeElement
does retarget but you can still observe the shadow state by checking :focus
.
But if you use an internal pseudo-class and change the computed style as a result, doesn't it defeat the purpose?
I might be misremembering some other more compelling reason for this behavior?
cc @annevk @rniwa
That seems like an explanation for why it matches :focus
, but not why it would match :focus-visible
.
I don't know why it matches :focus-visible
, but it's matching it in Chromium implementation.
Checking :focus-visible
spec there's not any mention to this specifically. The ShadowRoot
matches :focus
so it looks like Chromium determines that it also matches :focus-visible
. From :focus-visible
spec the only part related to that could be:
The :focus-visible pseudo-class applies while an element matches the :focus pseudo-class and the user agent determines via heuristics that the focus should be made evident on the element.
I was wondering if the list of suggestions we could include something specifically about this, mentioning that if ShadowRoot
matches :focus
because some of their descendants match it, it shouldn't match :focus-visible
. But maybe you believe this is not needed and every engine can decide what to do here.
Related HTML issues:
@rniwa next time you add new UA style sheet rules please file an issue against whatwg/html 😊
Is there any text anywhere about the intent of delegatesFocus
?
I don't know a lot about this topic, but I have found this Chromium bug (https://crbug.com/1014091) which mentions
Recently the spec for :focus has been updated, now if an element in a shadow tree is focused, the :focus selector should match on the host too, regardless of delegatesFocus. Currently in Blink it only matches when delegatesFocus is true, I think.
And it links to https://github.com/whatwg/html/pull/4731.
delegatesFocus
seems to be in the DOM spec, but I'm not really sure if I get the definition there: https://dom.spec.whatwg.org/#shadowroot-delegates-focus
Thank you for digging! I had found the same lack of definition in the DOM spec, but the whatwg bug might provide more clues.
Also found a mention to delegatesFocus
in the HTML spec: https://html.spec.whatwg.org/#focus-processing-model
Yeah, DOM just defines the member, HTML defines behavior.
FWIW, it would be problematic for :focus-visible
to become a way of detecting whether there is a shadow root or not.
FWIW, it would be problematic for :focus-visible to become a way of detecting whether there is a shadow root or not.
Do you mean that you could know or not if an element is a shadow root by focusing it via script (host.focus()
) and then checking it matches :focus
but not :focus-visible
?
I believe in WebKit you can do something similar already, as elements with :focus
have an outline, you could do host.focus()
and then check that host
actually matches :focus
but the outline-style
is none
. It would be a way to detect the same thing form a script somehow (e.g. https://cdpn.io/mrego/debug/WNorXNv/bZAQWKNVvEyM).
In any case, by design :focus-visible
is not guaranteed to match when an element is focused, so at best it would be a way to heuristically detect that something maybe-probably has a shadow root.
Compared with the user harm from authors disabling focus styling, which is the problem :focus-visible
is intended to solve, detecting that something might have a shadow root seems like it's at the opposite extreme of the priority of constituencies.
BTW, one of the HTML issues linked before (whatwg/html#3748), ends up in a CSSWG issue #3248.
The CSS Working Group just discussed [selectors] :focus-visible and Shadow DOM
.
For reference, what I mentioned during the discussion is that if we want to bubble :focus-visible
to the host (which is unclear to me) we should make it so that UA stylesheets don't match them both inside and outside the shadow root.
I think probably just do the simple thing is better though.
Hey @emilio, regarding this last comment:
I think probably just do the simple thing is better though.
Which solution were you proposing?
I think that meant "matching :focus-visible only on the actual element, not on its shadow host(s)".
My plan here is to write a test to check that behavior, and include some text related to that in a PR for HTML spec describing when the UA should show a focus ring.
The spec doesn't mention anything of what happen on a
ShadowRoot
is the root of an element that is focused. TheShadowRoot
matches:focus
(see HTML spec) but I believe it shouldn't match:focus-visible
or you'll get 2 outlines.WebKit has implemented a
:-webkit-direct-focus
internal pseudo-class to avoid this issue (see bug #202432)Example:
Here if you focus the
<input>
you'll get 2 outlines right now in Chromium (one in thehost
and another in the<input>
, both match:focus
which is right, and also:focus-visible
). That won't happen in WebKit thanks to that special UA stylesheet rule. In Firefox it looks like there are other problems because thehost
doesn't match:focus
.So the question is, should the
:focus-visible
spec include some text about this and describe WebKit's behavior?CC @alice @emilio