-
Notifications
You must be signed in to change notification settings - Fork 690
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] :focus-visible matches on initial programmatic focus #5885
Comments
Yeah, we probably should have included that in the heuristics listed in the spec when we added it in our implementation. I suspect I was just exhausted at the time. I would support adding some language as the second bullet point (after the comment about user preferences) like:
|
I think we should consider 2 cases:
<div id="target" tabindex="0">Target</div>
<script>
window.addEventListener("load", () => target.focus());
</script>
<div id="target" tabindex="0">Target</div>
<script>
setTimeout(() => target.focus(), 1000);
</script> I guess we want |
Hm, what happens in the second case after a https://codepen.io/sundress/pen/WNGqobM tests the same thing, but after a user has interacted with the page, blurring the previously active element before the delay. In my testing, Chrome "remembers" the previous value for It seems that Firefox has not (yet?) implemented this suggested heuristic: "If the active element matches :focus-visible, and a script causes focus to move elsewhere, the newly focused element should match :focus-visible." What do you think the behaviour should be for this case? |
Firefox implements that heuristic. But there's no active element since blur() was called, so that heuristic doesn't apply, what am I missing? |
If you're on mac, buttons don't get focused by mouse. That's platform behavior (WebKit does the same). |
It seems to me that if there's no previous active element (so, blur() was called, or there's no focused element or what not), showing the outline is the sensible thing to do. That heuristic seems to agree (or my reading of it, maybe?). How is the user supposed to know what's focused otherwise? |
Firefox implement the heuristics in the first comment as it passes I believe I'm aligned with @emilio, I don't really care if this is just after page load, or after the user has interacted with the website. In my mind, if nothing is focused (there's no active element), and a script focus something, it's good to match So maybe the 2 heuristics in the spec could be reworded in just one, something like:
|
I updated the codepen to use focusable divs instead of buttons - focusable divs are focused on click in WebKit and Firefox. Now I can see that Firefox shows a focus outline after programmatic focus after a We didn't write the current language into the spec by accident; it was the result of a lot of thought and discussion, for example: WICG/focus-visible#88 A couple of questions to think about:
|
Sure, and I agree with the spec language :). I guess the "no active element" case really kinda falls through all the conditions of the spec, though I think the Firefox behavior is the right one, because otherwise you don't show outlines for random focus moves that the user has no way of knowing about.
I expect the current spec language is pretty useful to do stuff like: Click a button, open a menu, move the focus to that menu, or stuff like that.
I don't know how this question is particularly relevant to this issue, but I agree that elements that accept keyboard input should always trigger focus-visible. |
There's not much practical difference between newFocusTarget.focus(); and
Why should they result in different behaviour?
Agreed, that is what the current spec covers - those are cases where a user interaction has caused focus to move, so we cue off the user interaction. It's exceptionally hard to think of a case other than immediately after page load when an author would move focus not in response to a user interaction. Given that Firefox and Safari have internally inconsistent (but consistent with the operating system) behaviour for focus on click on macOS (focus is set when clicking a focusable
It's relevant to this earlier question:
My answer is that if the user is not about to use the keyboard, they don't need to know, and the remainder of the rules (including my proposed language from #5885 (comment)) ensure that in the majority of cases where they would be likely to be interested in what element is focused, the focus is shown. |
Well, because the way you're "transferring" the knowledge of whether focus came from a pointing device or keyboard or what not in the rules in the spec is via whether the previously focused element matched
Well, sure, but you can't guess intent from a |
As a UI developer, I like the current heuristic on paper. It’s simple enough that it can be explained, which helps to a) use it right and b) work around it in edge cases. But if I understand it right, the specifics of “no focus for clicked buttons” on macOS (WebKit and Firefox) make things much less straightforward when clicking a button then moving the focus programmatically. Is it correct that it makes it impossible, on macOS, to programmatically move focus to a target element — e.g. the first focusable element in a modal — after a click on a button and have This could mean that we will have to avoid using
The only workarounds I can think of all damage accessibility, e.g.:
|
So, it seems there is some confusion here and I think that some of this actually comes from how we have written things as much as anything else. Here are the current heuristic rules from the spec. They are bullets in the spec, but I am using numbers to make it a little easier to compare, but I guess I also think they are ordered points...
I kind of think that we're getting trapped in some words/phrasing... I think this is the problematic part "If the active element matches :focus-visible, and a script causes focus to move elsewhere". I believe that what I am seeing is mostly that how it is being read isn't uniform: Emilio has interpreted this (I think) as "as focus is initiated, look to see if there is an active element". Thus, if a blur has happened, there isn't, so to him his treatment makes sense. However, maybe a better way to say this is ""we look at how they last interacted with the page". Thus, if you look at rego's examples, and consider Alice's followons about blur and her pens, you can see that she is trying to show that's not right. I kind of personally feel like our initial take on this which talked somehow about modality was important. I kind of still wonder if there should be some concept like that, as least in words (though, in practice even a prop might be good)... In any case, I have attempted to provide a modified set of rules that @alice and I, I think, would agree too and I wonder if make the intents clearer?
|
The CSS Working Group just discussed The full IRC log of that discussion<dael> Topic: [selectors] :focus-visible matches on initial programmatic focus<dael> github: https://github.com//issues/5885 <Rossen_> q <dael> rego: This is about if focus-visible should match after programmatic focus. Current heuristics, though not normative, talk about if active element matches then next element will match. Spec didn't mention anything about if there's no active element <dael> rego: Proposal is to change a bit so instead of saying it's the active element, you have to check last user interaction. ANd if none you match focus-visible. But if someone clicked a button and there was blur you wouldn't match b/c first was not a mouse <dael> emilio: What interactions count and which don't? That's an issue. I think current heuristic is fine. It's a problem on mac b/c mac doesn't focus a bunch when you click on it. A lot of programs when you click and then move focus the heuristics say button wasn't focused so new thing shouldn't mtach <dael> emilio: On mac since element isn't focusable by mouse you hit this issue. Good thing to come up with something that works. Gneerally agree with proposal, but which interactions count and which don't? I want the definition to be clear <dael> emilio: Does an interaction a second ago prevent programmatic focus from matching? <dael> florian: Confused. Are we trying to define when a UA shows a focus ring? If not, why defining when focus-visible shows? <dael> rego: Everyone is following heuristics. If we have clear heuristics then it's better <dael> florian: They're supposed to be heuritstics about when they show focus ring and focus-visible matches. <dael> emilio: True <dael> florian: So we're talking about the combo, not getting out of sync <dael> emilio: Right <dael> emilio: I'm okay with the proposal. I jsut want whatever this interaction means to be clarified <dael> florian: Wondering if right spec and place. I htink CSS spec has what it needs. We match browser focus ring and the pseudo class. When the browser shows focus feels more like HTML. Should we move them and call them normative? <dael> emilio: It's an option. Fine with that <dael> florian: If discussing state of doc and state of UI it's not a very css-y topic <dael> fantasai: This text is just an example. It's not normative <dael> florian: If you want normative it belongs in HTML, right? <dael> Rossen_: What are we doing with this? <dael> rego: Keep going on the issue and see if we should move this <dael> florian: Just before we wrap up, my impression is even though called heuristisc we're trying to harmoize browsers about when they show/don't show focus ring <dael> Rossen_: And make it more detectable <dael> florian: We have detectable. We have the pseudo class that matches browser behavior. If we want to define browser we should have that in html <dael> Rossen_: I think right next step are add any pseudo class discussions in the topic and rego will continue working with html group to see if there's additional behavior to define there |
From the last time we discussed this:
I think it's important we define this, does a random click on any part of the page is an interaction related to this or not? And there are other kind of special situations in which it'd be nice to define what's a meaningful interaction regarding these heursitics. For that reason I created a series of tests with different examples and use cases (maybe more could be added), it'd be nice to reach an agreement in how they should work before we can prepare the spec text (even the the spec text would be for HTML spec and not the CSS one): web-platform-tests/wpt#27806 |
…lt. r=mac-reviewers,bradwerth,mstange This aligns Mac's focus model with other platforms. Matches Chromium, but not Safari. Reasons why I think it's worth making this change: * Consistency with all other platforms. * Makes the :focus-visible implementation more useful. * Fixes focus navigation after e.g. clicking a button. * Shouldn't cause a lot more outlines to show up (at least not by default). An example of the second point: data:text/html,<button onclick="this.nextElementSibling.focus()">Click</button><button>Imagine I'm a dialog close button or something</button> In non-macOS platforms, we won't show an outline for the button in that case, which matches the developer expectations (links below). We don't show the outline because the focus comes from an element that has been focused by mouse (and thus didn't show an outline). But on macOS that doesn't work, because the button is not focused. For completeness, the actual heuristics for :focus-visible may change a bit as a result of the discussions in: * w3c/csswg-drafts#5885 * web-platform-tests/wpt#27806 But it's not clear to me how to best define this so it works on the macOS focus model. An example of the third point: data:text/html,<input type=text><input type=submit><input type=text> On Safari and Chrome (and Firefox on non-macOS platforms), clicking the button, then pressing tab, goes to the input on the right. In Firefox on macOS it doesn't because the button doesn't gain focus nor is selectable. Differential Revision: https://phabricator.services.mozilla.com/D108808
What we implemented before this patch was basically what the heuristics in the spec said, which used to be normative: https://drafts.csswg.org/selectors/#the-focus-visible-pseudo That has become non-normative and there's ongoing discussion on what should happen for cases like this in: w3c/csswg-drafts#5885 web-platform-tests/wpt#27806 There seems to be agreement on that WPT issue on cases like this one, so let's make it work. Differential Revision: https://phabricator.services.mozilla.com/D108805
What we implemented before this patch was basically what the heuristics in the spec said, which used to be normative: https://drafts.csswg.org/selectors/#the-focus-visible-pseudo That has become non-normative and there's ongoing discussion on what should happen for cases like this in: w3c/csswg-drafts#5885 web-platform-tests/wpt#27806 There seems to be agreement on that WPT issue on cases like this one, so let's make it work. Differential Revision: https://phabricator.services.mozilla.com/D108805
What we implemented before this patch was basically what the heuristics in the spec said, which used to be normative: https://drafts.csswg.org/selectors/#the-focus-visible-pseudo That has become non-normative and there's ongoing discussion on what should happen for cases like this in: w3c/csswg-drafts#5885 web-platform-tests/wpt#27806 There seems to be agreement on that WPT issue on cases like this one, so let's make it work. Differential Revision: https://phabricator.services.mozilla.com/D108805
Hi all, Well i agree with @mrego "the user interacts with the page" is not clear. In this example the rule number 4 fails when we mouse-click on an element that is not focusable and we move focus to another element with an initial programmatic focus. Current behavior:As long as we dont click on focusable element the :focus-visible will always match after initial programmatic focus. Please check the example for detailed scenarios. |
Is there any discussion to drop this ":focus-visible matches on initial programmatic focus" heuristic? I'm trying to understand why it behaves like this by default. It breaks my intuition. I have experienced two wrong end-user behaviors that feels like comes from this heuristic:
Screen.Recording.2024-07-14.at.01.38.14.mov |
I think the heuristic generally makes sense. If there's a programmatic call where it doesn't you can pass |
@emilio to rely on
Maybe it would make sense to have |
Wdym? False is supported, MDN is just wrong. The spec differentiates between true, false, and not provided (which is where the heuristic kicks in) |
@emilio I see only a mention of the behavior when ![]() https://html.spec.whatwg.org/multipage/interaction.html#dom-focusoptions-focusvisible |
Right, thus if it's false it never indicates focus, which means it'll not match the pseudo-class. The spec seems clear, but I wrote it so I'm obviously biased :) But the spec is basically saying (in JS terms):
Right? Which means that the false case is well-defined, it just works by not indicating focus. I'll send an MDN PR tomorrow once I'm on my desktop, if I don't forget :) |
@emilio it feels like this contradict this issue description:
|
That test is not using |
We have a test
focus-visible-010.html
that checks that a programmatic focus on the load event, causes that the element getting focused matches:focus-visible
. This test passes in the 2 implementations of:focus-visible
(Chromium and Firefox).However the spec doesn't mention anything about this in the suggestions list, and given that 2 browsers follow that, and we have a test, maybe it'd be nice to add that to the list too.
The spec mentions 2 cases of programmatic focus:
But it doesn't mention what happens when there's no active element before the programmatic focus. WDYT?
CC @alice @emilio
The text was updated successfully, but these errors were encountered: