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

Clarify "focusable" in the context of tabIndex IDL attribute #4464

Closed
muan opened this issue Mar 29, 2019 · 1 comment
Closed

Clarify "focusable" in the context of tabIndex IDL attribute #4464

muan opened this issue Mar 29, 2019 · 1 comment

Comments

@muan
Copy link
Member

muan commented Mar 29, 2019

Prior discussion for tabIndex IDL attribute can be found in #1786. But as far as I can see, that isn't an issue anymore (can be closed?). Specifically:

Chrome / Safari always return -1 for HTML elements that are not focusable (even after setting tabIndex to something else).

Major browsers all seem to reflect the values consistently now.

Current behavior of tabIndex

Test page: https://html-is.glitch.me/tabindex.html

UA/Results:

Chrome Safari Firefox
tabIndex values for chrome tabIndex values for Safari tabIndex values for Firefox

Spec

The tabIndex IDL attribute must reflect the value of the tabindex content attribute. Its default value is 0 for elements that are focusable and −1 for elements that are not focusable. https://html.spec.whatwg.org/#dom-tabindex

So my first question is: what determine "elements are focusable"?

@domenic kindly pointed out that there is specification for focus. However it is unclear if this would/should be the "focusable" definition for tabIndex?

In the focus specification, it mentions that "specifically focusable", "being rendered", and "actually disabled" are some of the characteristics considered when determining "focusable". As far as I can see, across the board, tabIndex do not consider them.

  • a without href is (theoretically) not "specifically focusable", but tabIndex is 0.
  • button[hidden] is (theoretically) not "being rendered", but tabIndex is 0.
  • button[disabled] is "actually disabled", but tabIndex is 0.

Motivation

Web developers often want to manage focus manually, most commonly in the case of the "tab trapping" behavior required for dialog patterns. To trap tab within a container, we will need to be able to tell what elements are indeed "focusable", but there is currently no easy way to do this. tabIndex is the closest thing we have, but not close enough.

For example, this is what we currently would need to do (non-exhaustive):

function focusable(el): boolean {
  return el.tabIndex >= 0 && 
    (el.tagName !== 'A' || el.hasAttribute('href')) && 
    (!el.type || el.type !== 'hidden') && 
    !el.disabled && !el.hidden && 
    !el.closest('[hidden]')
}

If tabIndex isn't suitable for this use case, it'd be great if we can get a isFocusable() check on elements. I'd be happy to open a new issue as needed once tabIndex's focus determination rule is clarified.

@annevk
Copy link
Member

annevk commented Apr 5, 2019

The discussion in #938 has some (I think) helpful context here. In particular we might need to define multiple groups.

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

No branches or pull requests

2 participants