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

Changing focus outline for tabindex="-1" has undesired side effects #29875

Closed
artopaavola opened this issue Dec 18, 2019 · 9 comments
Closed

Comments

@artopaavola
Copy link

artopaavola commented Dec 18, 2019

Removing indiscriminate outline suppression for tabindex="-1" elements in version 4.4.0 causes undesired side effects in vanilla js behaviour.

An example: When element.scrollIntoView() is used with focus() there will now be an outline around the element which has been scrolled into view. In case you are wondering, the focus must be programmatically moved to the element so that keyboard focus will also follow the scrollIntoView.

Tested on macOS with Chrome 79, Safari 13.04 and Firefox 71.0

@danielnixon
Copy link
Contributor

scrollIntoView() is unrelated to what's happening here. It's the call to focus() that is moving focus, which is triggering the focus outline styles.

the focus must be programmatically moved to the element so that keyboard focus will also follow the scrollIntoView.

Yep exactly. And focus must be visible:

If you absolutely must remove focus outlines (but why?), consider using the :focus-visible polyfill so focus outlines are only hidden from mouse users, not keyboard users.

@artopaavola
Copy link
Author

You are right, scrollIntoView() is unrelated for the focus styles but I thought the example would make more sense with the scrolling behaviour.

It's clear that focus must be visible for keyboard actionable elements, but I disagree that the focus outline must be visible in my example on the heading where the focus is set programmatically. Are you sure, that WCAG means that focus styles must also be visible on non-keyboard actionable elements? I haven't found anything on that in WCAG. For example, the links to WCAG specs that you provided are only talking about focus styles on keyboard actionable elements.

@danielnixon
Copy link
Contributor

People with attention limitations, short term memory limitations, or limitations in executive processes benefit by being able to discover where the focus is located.

Even if clicking your focused heading has no effect, there must be some reason you're moving the focus to heading (so that focus is moved to the heading at the start of a new dynamically rendered section/page, I assume). In that case, there's value in having the visual indication of where focus currently is because it makes clear what will happen when the user presses tab or shift+tab to move the focus forward or backward.

Removing the focus indicator is needlessly disorienting. Why remove it?

@patrickhlauke
Copy link
Member

Because arguably focus indication denotes something that interactive and actionable to some users, who may then be disoriented when they try to activate/trigger something they think it's interactive when it's not.

FWIW there's disagreement on this point even in AGWG w3c/wcag#1001

@artopaavola
Copy link
Author

My original case is almost exactly like one of the examples in Patrick's link.

When submitting a form, focus is sent to the container of an error message above the form.

The container has role="alert"and I think it shouldn't have an outline like it now does with Bootstrap 4.4.1.

@mdo
Copy link
Member

mdo commented Jan 12, 2021

@patrickhlauke Is this something we should leave open and act on?

@patrickhlauke
Copy link
Member

patrickhlauke commented Jan 12, 2021

personally, i'd say our current approach of suppression is fine (since the topic itself is open to discussion even in AGWG, see #29875 (comment)).

we could consider adding a future-proofed :focus-visible tweak in v5 that always shows a very minimal outline even for tabindex="-1" elements (undoing the suppression for keyboard users) though.

@patrickhlauke
Copy link
Member

Revisiting this, essentially what the change in #28437 did was to essentially not forcibly reset/normalise browser behavior for whether or not they add an outline to vanilla elements with tabindex="-1" when clicked with mouse/tapped. Some browsers - I think at this point, just Safari - still apply a visible outline by default for any arbitrary element with tabindex="-1" when clicked/tapped. All other current versions of browsers now don't do it by default.

Noting this is not necessarily a bootstrap problem, as Safari does this for completely vanilla HTML. what bootstrap used to do before #28437 was to explicitly suppress this default behavior, but it did cause issues at the time where some of our components then ended up having their default outline suppressed.

I think the positives of the change outweigh the inconvenience of the reboot now not explicitly suppressing Safari's default behavior. Noting that when/if Safari also supports :focus-visible, the end result will likely be the same, as that pseudo-selector basically applies to situations "if the browser would by default show the default outline if it was focused by the user in the way they just did", and since Safari does do this by default for arbitrary HTML elements with tabindex="-1", then even the explicit extra :focus-visible styling won't make a difference. we'd have to go back to indiscriminately suppressing outline any time a tabindex="-1" element receives focus, which is too heavy handed in my opinion as a reset.

If authors want to suppress this behavior specifically for their vanilla elements/interactions, they will have to add the explicit suppression in themselves, I'd say. Closing for this reason.

@patrickhlauke
Copy link
Member

patrickhlauke commented Feb 9, 2021

adding that Firefox on macOS, but not on Windows, seems to have taken a weird halfway-house approach of showing the focus outline on tabindex="-1" arbitrary elements when they receive programmatic focus, but not when clicking/tapping. Likely due to Firefox's attempt to usually mimic what Safari does on the platform. Chrome on macOS now doesn't show the outline on arbitrary tabindex="-1" elements that receive focus, regardless.

Long story short, the issue at its core now becomes: do we want reboot.css to forcibly suppress this particular quirk between Windows browsers (where the outline doesn't show at all), and macOS (where Safari and Firefox do show an outline)? (i.e. The issue should be "Make reboot explicitly suppress outline for any arbitrary elements with tabindex="-1" that receive focus" - as currently reboot does the opposite of explicitly suppressing outline only in cases where the platform would supress it as well by default, so reboot kind of enforces the opposite at the moment). I'd say not, as it's a bit heavy-handed a change for reboot. (i'd even go the opposite way and say that we could consider removing our current [tabindex="-1"]:focus:not(:focus-visible) as, if we're careful with component-specific styles, we should never need to actually rely on that ourselves)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants