DIVs with overflow receiving focus, causing issues for accessibility user
Categories
(Core :: DOM: Selection, defect)
Tracking
()
People
(Reporter: kaushik.patel, Unassigned)
References
Details
Attachments
(2 files)
User Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36 Steps to reproduce: User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b9) Gecko/20100101 Firefox/4.0b9 Build Identifier: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b9) Gecko/20100101 Firefox/4.0b9 An div element with overflow-y:hidden in its style is focusable Reproducible: Always Steps to Reproduce: <html> <body> <input> <div style="overflow-y:hidden"></div> <input> </body> </html> Actual Results: div is focusable Expected Results: div should not receive focus up on tabbing Actual results: Accessibility user uses keyboard TAB key to navigate across the Web-Page. In the above case, the DIV receives the focus and nothing can be announced by Screen Readers , creating confusing and usability issue for these users. Ours is a Web Based Enterprise application and this issue is critical for us to receive 508 compliance for us Expected results: Div should not receive focus
Comment 1•10 years ago
|
||
Kaushik, This doesn't need to be security sensitive. Please don't change the priority. Leave that to the developers. You filed this under version 32 but the actual useragent values were for a beta version of Firefox 4.
Comment 2•10 years ago
|
||
Updated•10 years ago
|
Comment 4•10 years ago
|
||
I cannot reproduce this on Windows using Firefox 32 or 35 Nightly, with either NVDA or JAWS. Both inputs are focusable just fine and I can type in them. No problem as far as I can see.
Comment 5•10 years ago
|
||
Thanks Marco! Kaushik, it is not clear to me what build you were actually testing. If it was really Firefox 4 beta, that is far too out of date. I'm going to mark this as works for me. Please read https://developer.mozilla.org/en/Bug_writing_guidelines and if you can reproduce it with a current build, please reopen and give us detailed instructions on how to reproduce and exactly which build you were using. Thanks!
I have attached the sample HTML where the DIV receives the focus.
Comment 9•10 years ago
|
||
Kaushik, that attachment was only example data and did not in any way contain real information on names and salaries?
Comment 11•10 years ago
|
||
I can reproduce the focus issue with Nightly 35 on Linux. Marco, which product/component should we put this?
Reporter | ||
Comment 12•10 years ago
|
||
Ya..the data in the table is just an example data
Comment 13•10 years ago
|
||
I still don't see the problem, or I didn't understand it. To me this looks like a contentEditable table that I can navigate with my Windows screen reader. Note that contentEditable for tables is not well defined and in general behaves badly. This is an Editor bug, IMO.
Comment 14•10 years ago
|
||
Marco, when I tab in Firefox the focus changes from the urlbar to the search input to the document and then to the table. In Chrome 37 the urlbar is focused and blurred only. I'll move this to Core Editor for triage.
Comment 15•10 years ago
|
||
Confirming that <div style="overflow:auto"> is focusable in Firefox 37 Mac. Focus can be set by script and keyboard, however not by mouse. A simple test case can be found here: https://jsbin.com/biyapa/1/edit Chrome 42 and IE11 do not show this behavior. Note that https://bugzilla.mozilla.org/show_bug.cgi?id=626919 looks like a duplicate (or this one is, since the other issue is older).
Comment 16•9 years ago
|
||
To be clear, despite the example in the first post, this bug occurs whenever a scrollbar is present. This can be with overflow-x or simply overflow: auto. For anyone experiencing this bug, setting a normally unnecessary tabindex="-1" can disable the focusing.
Comment 17•8 years ago
|
||
This issue is still not fixed in v.45.2.0. Are there any plan to get this issue fixed in the upcoming versions? - It's not a fare idea to keep adding tabindex='-1' to every element (having overflow:auto) only for firefox browser.
Comment 18•8 years ago
|
||
(In reply to satheeshdom from comment #17) > This issue is still not fixed in v.45.2.0. Are there any plan to get this > issue fixed in the upcoming versions? > - It's not a fare idea to keep adding tabindex='-1' to every element (having > overflow:auto) only for firefox browser. I agree with satheeshdom, is this going to be fixed any time soon? Pretty big issue and it's only in Firefox.
Comment 19•8 years ago
|
||
+1. The "tabindex=-1" has the rather unpleasant side effect of making nodes click-focusable.
Comment 20•8 years ago
|
||
per comment #15's sample, this doesn't use contenteditable. Is this Core: Selection or DOM: ?
Updated•8 years ago
|
Comment 21•7 years ago
|
||
Hello, This is what I've found out: When a div contains an element that is bigger (either taller or wider) than the parent and has the property overflow-x or overflow-y set to any value, then it can receive the focus. See an example below: https://codepen.io/alexcanessa/pen/JNmdgN Testing on: MacBook Pro (Retina, 15-inch, Late 2013) Firefox 53.0.2 OS 10.12.3 (Sierra)
Comment 23•4 years ago
|
||
A more accurate title is "DIVs with [scrollable] overflow receiving focus, causing issues for accessibility user".
Here is a minimal reproduction of the behavior https://jsfiddle.net/sjnpd04v/
This behavior may be beneficial, when the scrollable element contains no focusable children. If the scrollable element would not be able to receive focus, then a keyboard-only user would not be able to focus and scroll the element. This is in fact the case in Chrome, where in the test case above you can not focus the .focusable
div.
When the scrollable element does have focusable children, tabbing through the container becomes unnecessary.
As Craig points out, adding tabindex="-1"
makes the element click focusable on both Firefox and Chrome.
The issue is that it is considerably more difficult to stop this behavior than it is to enable it, which can be done with tabindex="0"
on elements you want to receive focus.
I'm not aware of any way to stop this behavior without JavaScript and even then I don't know how it should be done.
Comment 24•4 years ago
|
||
(In reply to M from comment #23)
This behavior may be beneficial, when the scrollable element contains no focusable children. If the scrollable element would not be able to receive focus, then a keyboard-only user would not be able to focus and scroll the element. This is in fact the case in Chrome, where in the test case above you can not focus the
.focusable
div.
Indeed, and that is precisely why this behaviour was implemented (a long time ago).
When the scrollable element does have focusable children, tabbing through the container becomes unnecessary.
That's true, and in principle, I guess it'd be nice if the scrollable area wasn't focusable in the presence of focusable descendants. In practice, while I'm not super familiar with that area of the code, I imagine trying to actually implement this (accounting for dynamic mutations, CSS hiding, etc.) would be fraught with nasty edge cases and a world of pain.
As Craig points out, adding
tabindex="-1"
makes the element click focusable on both Firefox and Chrome.The issue is that it is considerably more difficult to stop this behavior than it is to enable it, which can be done with
tabindex="0"
on elements you want to receive focus.I'm not aware of any way to stop this behavior without JavaScript and even then I don't know how it should be done.
Add a mousedown listener which calls event.preventDefault(). I realise this might not be feasible in some cases due to other side effects (e.g. it will stop drag events from firing), but I thought it worth noting as a potential solution.
Comment 25•4 years ago
|
||
To be clear, I understand the concern for screen reader users here and it obviously isn't ideal. However, it also wouldn't be ideal if a keyboard only (non-screen reader) user couldn't scroll. I'm not sure we can reasonably sacrifice one for the other.
Comment 26•4 years ago
|
||
Hi James, thanks for the comments! That certainly helps clarify things, and I agree that it is useful and Inclusive for a scrollable element with no focusable children to be tabbable in this way.
In my particular use cases (both the one ~4 years ago and the one from yesterday), a role=listbox element is becoming tabbable in a way that a focus trap is created, which is of course its own (arguably worse) a11y issue. But, knowing that the scrollable-tabbable behavior is useful to some folks, we can work around it with the tabindex=-1 approach by adding an onFocus handler that redirects focus to an item in the listbox.
With that option, the most critical issue I'd like if we could improve here: the mysterious and undocumented behavior that results in my coworkers pulling their hair out trying to figure out why an element without a tabindex is suddenly tabbable, and in only one browser! At the very least it would be great if this was documented somewhere on MDN. Scott O'Hara also mentioned in a discussion yesterday that this behavior was intentional, and added that Chrome had actually tried to ship something similar maybe ~1 year ago but ran into some obstacles. So, perhaps this should also be brought up in the context of a W3C discussion to evaluate whether it belongs in a standards proposal.
Another idea I had -- and I don't know how feasible this would be in terms of both the browser engine and the OS native UI primitives -- would be to focus the scrollbar itself, rather than making the scrollable element tabbable. That would allow e.g. a sighted keyboard-only user to scroll the overflowing element in a way that is handled by the engine/OS, rather than handled spookily inside the DOM. I can't say I've ever seen a pattern like this before (maybe in early DOS days?), but an option I wanted to throw out :)
Thanks again for the attention on this.
Comment 27•3 years ago
|
||
Another issue with the status quo (for sighted keyboard users) is that these scrollable elements when focused do not have any default browser focus indicator. This violates WCAG 2.1 2.4.7 Focus Visible.
I'm also curious what exactly the heuristic is that FF uses to determine whether to place a scrollable element in the tab order? If it's documented somewhere (maybe on MDN as Craig mentioned above), then it'd be easier developers to target these elements when writing code (i.e. to do things like override the default browser focus indicator for all scrollable elements that FF has decided to put in the tab order).
Comment 28•3 years ago
|
||
(In reply to zelliottm from comment #27)
Another issue with the status quo (for sighted keyboard users) is that these scrollable elements when focused do not have any default browser focus indicator. This violates WCAG 2.1 2.4.7 Focus Visible.
How not? When I tab the testcase above I do get a focus ring.
I'm also curious what exactly the heuristic is that FF uses to determine whether to place a scrollable element in the tab order? If it's documented somewhere (maybe on MDN as Craig mentioned above), then it'd be easier developers to target these elements when writing code (i.e. to do things like override the default browser focus indicator for all scrollable elements that FF has decided to put in the tab order).
It's not quite an heuristic. The code is here, and it basically ensures that there's some scroll range, and it's an HTML element. So basically all scrollable boxes that you'd find. The other special-cases there are not particularly interesting, but I can explain them if you want.
Comment 29•3 years ago
|
||
How not? When I tab the testcase above I do get a focus ring.
My bad - I didn't notice the dotted, 1px outline. I was looking for the thick, blue focus ring that is rendered on form controls (https://codepen.io/zelliottm/pen/KKabavq) (I'm used to Chrome's keyboard focus indicator). I'm not sure if it meets contrast requirements per https://www.w3.org/WAI/WCAG21/Understanding/focus-visible-enhanced, but it's better than nothing. :)
Thanks for the link to the code. I guess the problem that I'm encountering is that I want to globally apply a stronger focus indicator to these elements, but I'm unable to do so with a CSS selector as I can with other tabbable elements (i.e. form controls, buttons, arbitrary elements with [tabindex], etc).
Comment 31•3 years ago
|
||
In my case that overmatches, I'd like to write as specific of a selector as possible. I think my best approach is to try to copy FF's logic with JavaScript to identify these elements.
Updated•2 years ago
|
Comment 32•2 years ago
|
||
I run into a similar issue implementing a table with virtual scroll capabilities.
<html>
<body>
<h1>Focus test</h1>
<div><button id="el1">focusable element 1</button></div>
<!-- virtual scroll viewport (should never receive focus) -->
<div id="viewport" style="padding:1rem;overflow:auto;width: 200px;height:50px;">
<table border=1>
<tr><td id="el2" tabindex="0">focusable element 2</td></tr>
<tr><td>cell</td></tr>
<tr><td>cell</td></tr>
<tr><td>cell</td></tr>
<tr><td>cell</td></tr>
<tr><td>cell</td></tr>
<tr><td>cell</td></tr>
<tr><td>cell</td></tr>
</table>
</div>
<div><button id="el3">focusable element 3</button></div>
</body>
Firefox focuses the viewport, which should not receive the focus at all.
TAB order(firefox): el1, viewport, el2, el3
TAB order(chrome, webkit): el1, el2, el3
The workaround setting tabindex="-1" to the viewport works, but may introduce other problems (make it focusable via mouse).
Comment 33•2 years ago
|
||
(In reply to dietmar from comment #32)
Firefox focuses the viewport, which should not receive the focus at all.
See comment 24 and comment 25 as to why this occurs. My understanding is that Chromium is looking at implementing this as well, as the inability to keyboard scroll a scrollable area is an accessibility problem. This got implemented in https://bugs.chromium.org/p/chromium/issues/detail?id=585413, though it got reverted and is now being discussed in https://bugs.chromium.org/p/chromium/issues/detail?id=907284.
Comment 34•2 years ago
|
||
First, thanks for those links.
For my use case, it would help if there is a way to disable that behavior without setting tabindex to -1.
Note: I am implementing some custom widgets that controls scrolling by themself (table with virtual scroll, ...).
Comment 35•2 years ago
|
||
So... https://searchfox.org/mozilla-central/rev/77a39e7595198fd30b57550749c15761d30314fb/layout/generic/nsIFrame.cpp#10276 is the relevant code. So ways to disable would be making the element not an HTML element or so... Alternatively, is making the element not focusable at all an option?
- Does setting
-moz-user-focus: none;
(setting-moz-user-focus: normal
back on kids) work? If it doesn't, I'd argue it probably should. - Making the scroller
visibility: hidden
and kidsvisibility: visible
would also work, but that might have the unintended effect of showing the kids unconditionally even if the ancestor is visible (plus hiding the scrollbar) which isn't amazing.
Comment 36•2 years ago
|
||
I want to stress that this is a feature of Firefox, not a bug.
Please do not try to override it unless:
- You give another (ancestor or descendant) container
tabindex="0"
; - You also give it an accessible name;
- You give it an appropriate role;
- And you provide some focus styles.
If you create a scrolling area that cannot be scrolled by keyboard alone, then you will have made a WCAG 2.1 SC 2.1.1 Keyboard (A) failure. If you do not assign an accessible name or role then you risk a 4.1.2 Name, Role, Value (A) failure. If you allow Firefox to scroll the content area for you then you are off the hook.
Given WCAG conformance is a requirement in many government and corporate contexts, creating a failure is a bad idea.
If you create your own "custom scrolling", then ensure a keyboard user can use it with only the keyboard. A scrolling table is quite easy to achieve with no script and very little HTML.
References:
- WCAG 2.1 SC 2.1.1 Keyboard (Level A): https://www.w3.org/WAI/WCAG21/quickref/#keyboard
- WCAG 2.1 SC 4.1.2 Name, Role, Value (Level A): https://www.w3.org/WAI/WCAG21/quickref/#name-role-value
- Keyboard-Only Scrolling Areas: https://adrianroselli.com/2022/06/keyboard-only-scrolling-areas.html
- Under-Engineered Responsive Tables: https://adrianroselli.com/2020/11/under-engineered-responsive-tables.html
Comment 37•2 years ago
|
||
(In reply to Emilio Cobos Álvarez (:emilio) from comment #35)
So... https://searchfox.org/mozilla-central/rev/77a39e7595198fd30b57550749c15761d30314fb/layout/generic/nsIFrame.cpp#10276 is the relevant code. So ways to disable would be making the element not an HTML element or so...
Sorry, I don't get that?
Alternatively, is making the element not focusable at all an option?
- Does setting
-moz-user-focus: none;
(setting-moz-user-focus: normal
back on kids) work? If it doesn't, I'd argue it probably should.
I tried that already, but it seems -moz-user-focus does not have any effect.
Comment 38•2 years ago
|
||
(In reply to Adrian Roselli from comment #36)
I want to stress that this is a feature of Firefox, not a bug.
Please do not try to override it unless:
- You give another (ancestor or descendant) container
tabindex="0"
;
Sure, I always make sure there is a focusable element inside...
If you create a scrolling area that cannot be scrolled by keyboard alone
Point is that my component is perfectly accessible without this firefox feature, and the firefox feature make accessibility worse in this case.
It would really help if I can simply set "-moz-user-focus: none;". But this does not have any effect. Is that expected to work?
Comment 39•2 years ago
|
||
This is a problem for multiple components in React Spectrum, Adobe's component library. We had a similar issue with our table component, which we initially solved by adding tabindex="-1"
to the scrollable element. However, now we realized that this has broken the accessibility tree - the role="presentation"
on this element is ignored and the extra accessible element breaks the grid hierarchy. Another similar case where this is broken is in our date picker component. In both cases we already have focusable children within the scrollable area, and allow the user to scroll with the keyboard so adding an additional tab stop is unnecessary. See issue here: https://github.com/adobe/react-spectrum/issues/3633. You can also see the problem in our docs if you make the window narrow so the date picker scrolls: https://react-spectrum.adobe.com/react-spectrum/DateRangePicker.html.
I can also confirm that -moz-user-focus
does not appear to have an effect, but it would be nice if it did. Perhaps the heuristics could also be improved if there is a focusable element within the scrollable region?
Comment 40•1 year ago
|
||
This also causes problems for a use-case we have in our Next.js app. We have this search box that reflects its value to the URL using Next's router.replace
. The problem is that when there's a scroll container, it just steals the focus in the middle of typing in the input, which is just bad.
Here's a CodeSandbox: https://codesandbox.io/p/sandbox/tender-pine-9x9f38?file=/app/page.tsx:34,1
FWIW, this doesn't happen if I use history.replaceState
instead, but I'd prefer to not bypass the framework's router. I'll file an issue with them as well.
Comment 41•1 year ago
|
||
Here's the issue I filed with Next: https://github.com/vercel/next.js/issues/54838
Comment 42•1 year ago
|
||
As far as I know, Firefox only focuses scroll containers if the user or the page explicitly set focus to them. I don't know of any reason that any other API would focus the container. I wonder if Next's router.replace is calling focus on the container for some reason? That wouldn't impact other browsers, since the container isn't focusable there, but regardless, it's not the correct thing to do.
Comment 43•1 year ago
|
||
IIRC last time I interacted with this bug, scrollable containers were automatic tab stops.
Comment 44•1 year ago
|
||
Yes, they are, but that still requires explicit action by the user (tabbing). Comment 40 suggests that this is somehow happening without the user explicitly tabbing, which shouldn't be the case.
Description
•