-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
unexpected focus results for tabindex + <dialog>.showModal() #1929
Comments
Could you explain what parts of the behavior are unintuitive to you, what spec lines lead to that behavior, and what behavior you think should happen instead? |
https://html.spec.whatwg.org/multipage/interaction.html#specially-focusable
the simplest interpretation of this text is: in my fiddles: pressing Tab before |
Sorry, I'm still not really clear.
So, you would expect it to have the same results whether or not a modal dialog is shown? Which of the two results would you find more preferable? |
Dan and I chatted before filing this, and I think Dan's main concern is that "dialog focusing steps" depends on DOM order, and is not manageable by tabindex attributes. https://html.spec.whatwg.org/multipage/forms.html#dialog-focusing-steps
https://html.spec.whatwg.org/multipage/interaction.html#control-group
A solution would be
|
ehhh, that didn't sound so awesome when I spoke about it to @freshp86. I don't really understand what
right, this is what I was hoping for. but really, just that what i expect from fiddle 1:
i'll fill in more steps for 2 and 3, but same basic theme: pressing Tab in a document works differently than when opening a |
OK, thanks for the background; I think I am starting to understand the problem. It seems like the conflict is essentially that tabindex="" is used to impact sequential focus navigation, but most of the focus mechanisms in the spec do not have to do with sequential focus navigation---that's only related to pressing TAB to sequentially tab through the document. In particular, in fiddle1, the outside-the-dialog div is not focused at first because the whole browsing context is focused. And you cannot then focus it through pressing TAB, of course. But you can focus it by clicking on it. (Or by calling When you open the dialog, the user agent then wants to move focus to the dialog. Since this isn't related to pressing TAB, we don't care about the tabindex="" attribute; we just use the normal focus rules that apply for clicking and for I guess what might be strange is the choice to focus the first element of the dialog, instead of focusing the dialog as a whole. Focusing the dialog as a whole would match the behavior for the outer document, where we initially focus the browsing context instead of focusing the first focusable element inside of it. My guess is that it was deemed more user-friendly to focus something inside the dialog. Maybe it is also complicated since "the dialog" is kind of part of both the outer document and the dialog focus control group; maybe if we focused the dialog then the rest of the spec would get confused about what to tab to next, or similar. (I'm less sure about that part, and it doesn't matter much.) So I think there might be an inconsistency here, but I don't think extending tabindex="" to have meaning outside of sequential focus navigation is the right way to fix it. |
That's possible, but for assistive technology users that's like deeming it "more user-friendly" to start scrolled half-way down the page (if you focus something half-way in the middle of the dialog's contents, that's where a screenreader likely shifts to). Additionally, if there's a Also, focus rings are often just noise on mobile (other than maybe in editable areas i.e.
YES. It would be way more sane, IMO, to just focus the dialog as a whole and respect |
If you're interested in changing Chromium in that fashion, I'm happy to change the spec too. Let me know? |
I'm hacking around in Blink, but have some questions:
|
In my opinion,
|
@danbeam thanks for digging them up. If we were to make these changes, I'd say the answers to your three questions would be yes, yes, and yes. However looking through that first long bug thread does make it seem to me like the more reasonable behavior is to focus the first control. Testing a few native apps they seem to all work that way too. Do you still think focusing the dialog is the best choice? I was going to say, "maybe the best strategy is 1) autofocus; 2) first focusable control; 3) the dialog". But that is actually what the spec already does! The confusion in this thread is just about confusing "focusable" with "part of the sequential focus navigation order"; |
But that's exactly the issue: someone probably would add
Yeah, I understand what you're saying, and we're (Chrome UI folks) probably having issues because we're using Shadow DOM, which intentionally hides a bunch of stuff (and currently doesn't work with the way that In general, I think there's a few things we (and the context) agree upon:
What I'm not sure makes sense is:
Regarding 1. if we agree to let some validly opt out of the default behavior (initial focusing logic), maybe canceling a Regarding 2. I suspect that @Hixie, @cookiecrook, and @stevefaulkner went at eachother for many rounds because it wasn't insanely clear to them what tl;dr - the absolute best thing I could see happening is the ability to harness just inertness, maybe via an |
I like parameterizing show/showModal, among these. Although I'd appreciate more info on the use cases---I don't quite remember that showing up in the megathread, but maybe it escaped my brain...
Yeah, definitely! We're hoping for implementer interest in #1474, but haven't seen much yet :(. So to recap our learnings, there are three separate but related concepts:
The spec factors (3) separately from (1) and (2), but in practice they are tied together: the algorithms for focusing and sequentially navigating focus consult inertness, in addition to consulting focusability specifically and in-sequential-tab-order specifically. It might be an unobservable refactoring of the spec to say that all inert elements are unfocusable and not in sequential tab order. But probably there is some subtle difference; I wonder what it would be. So. What should we do with this bug, given our new deeper understanding of focus? Maybe add a clarifying note delineating the difference between these three concepts, for one. But should we do any behavior changes? Maybe parameterizing show/showModal? Or just hope that #1474 gains ground and the issues can be solved there? |
I like the idea of changing the spec so that opening a dialog respects autofocus, and doesn't autofocus controls with tabindex=-1. Those seem consistent with the spirit of the original spec, and they're unlikely to break any existing code or tests. I'm a bit hesitant to parameterize showModal because we're already having trouble getting buy-in to ship dialog in other browsers, so changing the API seems like it shouldn't be done unilaterally. |
Adding an optional Apparently easier than getting folks to agree on whether it should exist :). |
Speaking of the |
yep, that's why the proposal adds an optional dictionary (instead of just a boolean) -- there's a well-placed TODO in the code. |
@domenic You asked for use cases. We're targeting an action menu (code). Our use case is functionally similar to a native context menu but we need to control the style. We don't wish to match platform style, so A list of options shows up based on a user gesture. Tapping, clicking, or keyboard navigation within the action menu selects an item and performs an action. We wish for the menu to become "first responder" (get first crack at all UI events) until either an action is performed or the user expresses a desire to close the menu (perform no action) via keypress (Esc, Tab) or tap/click on the "scrim" (area outside the menu). This is similar to The modal aspect of The Polymer team has tried to mimic inertness without |
It already does; no spec change needed
As discussed in the rest of this thread, that doesn't make sense; tabindex=-1 means that the control is focusable, but not in sequential focus order. But sequential focus order is only used for pressing TAB, not for anything else (like determining what control should be initially focused in a dialog).
Yeah, dialog is in a tough spot. I think conservative small changes like this make sense though, as long as nobody else objects.
Maybe we should open an additional issue to discuss removing that, since nobody implements it. Unless Chrome wants to implement it? The use case @danbeam gives is a pretty clear-cut instance where an Element would be useful.
This seems like a pretty good use case for non-modal dialogs in my opinion... I'm surprised you're using the modal version. I see how it makes event management easier but it seems like it'd be better if clicking/etc. outside the "dialog" had the usual effect, like it does with native context menus. At least on Windows (which I understand most Chrome users are on). Anyway, I was specifically asking for use cases for not focusing the first focusable control. In your example, it seems like focusing "Make default" would be good, right? Or is the decision from the UI folks that it's better not to do so? I guess some quick testing of native context menus shows that they don't focus the first item usually, so that makes sense... |
For the use case in question (implementing a popup action menu with dialog), the existing API, even if implemented, would not be sufficient. Just passing an Element to Simply specifying an "anchor element" without a strategy on how to use that element's position is not sufficient I think.
Non-modal version (our previous "action menu" implementation, which was not
Have not tried on Windows, but on Linux, the 1st click outside of the context menu is consumed for closing the menu, which matches the behavior of a modal
Here is a screencast showing such a case, where a disabled custom element receives focus. |
Right, that's why https://html.spec.whatwg.org/multipage/forms.html#%27anchor-point%27 is part of the feature.
Yes, I noticed this discrepancy, but I assumed Chrome (desktop) would be building for 95% of its users using Windows, not the <1% using Linux.
It seems like the real problem here is that the custom element is focusable in the first place. Presumably because you added a tabindex attribute to it. Why do that? All custom elements are by default not focusable, so there's nothing to be gained here. |
It boils down to subtle differences between using a list box to perform an action vs select a value. Select a value When selecting a value (e.g. from an enumerable list), like in the case of
Perform an action In an action menu, an item is not preselected (nor preserved when re-opened).
Why does it matter? Simply because I (and others) want to convey the right paradigm. Unfortunately, in many of these UIs (and in Material Design, dropdown example), the focused state and the selected state (either selected value or action to perform) are identical. Why? ¯\_(ツ)_/¯ Less UI paradigms = better for users? Additionally, focus UIs are less useful on touch-only devices. So, for our use case, if That's why it's a big deal to me (and all the places I gathered screenshots). |
Wow, thanks @danbeam for the detailed explanation! I agree it makes sense in such a menu-like use case to not select the first item. OK. That's a reasonably compelling reason to add such an option to show/showModal. So, I can work on a spec change to do that. We need something that is false by default (unlike setInitialFocus); perhaps focusDialog. Should we also remove the anchor ability, or is Chrome interested in doing that at some point? I'd lean toward removing it unless there are concrete plans in the next quarter or so; we can always add it back later. |
Huzzah!
On the chrome side, I don't see a bunch of priority being given to the anchor idea: |
This was mentioned briefly in the discussion in #1929. <dialog> only has one implementation currently, and that implementation is not planning to implement the anchoring feature, per https://bugs.chromium.org/p/chromium/issues/detail?id=410346.
I put up #2157 to remove anchored positioning and thus clear the way for work on this option.
Hmm. We want to focus the dialog itself if it's focusable, right? We might also want to suggest that dialog elements be focusable areas by default. |
Given that JS does not support overloaded methods, I am afraid that committing to a There are a few things related to showing a dialog that should be specified at the time the dialog is shown (modality, initial focus behavior, end focus behavior, anchor element), and therefore those make sense to not be HTML attributes that can be modified after a dialog is shown. So instead of passing a single optional boolean to
I just think this is more flexible, and since specs are harder to change (especially if multiple vendors have already implemented them), making it a bit more forward looking could be beneficial. |
Yes, we would definitely use an options object. I don't think anyone was proposing otherwise. |
I've had a go at implementing the focus proposal in the polyfill here, if anyone wanted to play around with it (...in Firefox/Safari where Q. Currently, clicking on the dialog backdrop in Chrome's native implementation, focuses the dialog if it has a |
It's been almost a year since the last update on this, has there been any progress? |
@esprehn and I no longer work on Chrome, so ¯\_(ツ)_/¯ |
I believe the consensus was focusing the |
Ping. Where is this issue at? |
No, we don't have implementer consensus on this change anymore. @danbeam and @esprehn have moved on from working on Chrome, and @nt1m has not worked on dialog in Firefox recently or replied to this thread. (And no other browser implements dialog.) Consensus needs to be rebuilt before this change can be made, otherwise we are just writing fiction that no implementer will follow and for which tests will fail. |
This was mentioned briefly in the discussion in whatwg#1929. <dialog> only has one implementation currently, and that implementation is not planning to implement the anchoring feature, per https://bugs.chromium.org/p/chromium/issues/detail?id=410346.
Have there been any advances on this? The specification is almost a decade old and Chrome/Edge has full support for it, from an accessibility standpoint would be really nice to have full support. |
So it looks like we may want to match what ShadowRoot's delegates focus does here. I don't see why we want to have a different behavior with regards to finding the focusable shadow-including inclusive descendant. |
No, what I mean is that whatever we do with dialog should probably mach https://html.spec.whatwg.org/#focus-processing-model:delegates-focus and https://html.spec.whatwg.org/#flattened-tabindex-ordered-focus-navigation-scope and vice versa. i.e. dialog element should behave has if it's a shadow root which delegates focus to its descendant tree. Maybe dialog should be a focus navigation scope owner? |
Yeah, I think that was the conclusion we were coming to in #2393 (comment) . After re-reading the earlier posts in this thread, perhaps the two issues are really about the same thing in the end. |
@domenic @esprehn @tkent-google @TakayoshiKochi
Hi,
As spec'd (as far as I can tell),
<dialog>
has a few cases where thetabindex
+ focus behavior is unintuitive to me.Specs:
https://html.spec.whatwg.org/multipage/forms.html#dialog-focusing-steps
https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation-order
https://html.spec.whatwg.org/multipage/interaction.html#negative-tabindex
First case:
Second case:
Third case:
It's obviously possible to remove the
tabindex="-1"
in cases 2 and 3, but some frameworks (i.e. Polymer) use.tabIndex = 0/-1
as if it's the same as callingsetAttribute('tabindex', '0')
orremoveAttribute('tabindex')
.Additionally, there's no easy way to remove an element that is tabbable by default (i.e.
<button>
,<a href>
) without the ability to specifytabindex="-1"
.I think this generally boils down to spec lingo about the "tabindex focus flag" or being "focusable" when it should be more like being in the "sequential focus navigation order".
This leads to unexpected mismatches in behavior (at least in my mental modal) which actually manifested in Chrome's settings page.
Note: while this currently only affects Chrome, Mozilla seems to be kinda/sorta interested:
https://bugzilla.mozilla.org/show_bug.cgi?id=840640
The text was updated successfully, but these errors were encountered: