This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 23870 - FKA: No defined way to get keyboard focus into and out of a shadow DOM component
Summary: FKA: No defined way to get keyboard focus into and out of a shadow DOM component
Status: RESOLVED FIXED
Alias: None
Product: HTML WG
Classification: Unclassified
Component: HTML5 spec (show other bugs)
Version: unspecified
Hardware: PC All
: P2 enhancement
Target Milestone: ---
Assignee: Charles McCathieNevile
QA Contact: HTML WG Bugzilla archive list
URL:
Whiteboard:
Keywords: a11y, a11ytf, a11y_focus
Depends on:
Blocks: 24106
  Show dependency treegraph
 
Reported: 2013-11-20 00:37 UTC by James Craig
Modified: 2016-04-11 14:26 UTC (History)
10 users (show)

See Also:


Attachments

Description James Craig 2013-11-20 00:37:48 UTC
FKA (full keyboard access): There is currently no defined way to get keyboard focus into and out of a shadow DOM component. Some components (like the native "number" input type) don't need this, but others (like native video controls) need multiple tab stops inside the shadow DOM component.

For example: 

<input type="number"> 

Although there are multiple focusable elements inside (textfield, increment button, and decrement button), all features can be controlled with standard keyboard behavior. Focus stops on the input, and the increment/decrement buttons are activate with up/down arrows.


<video controls>

There are multiple controls in the shadow DOM component, including volume/mute buttons/sliders, a playback position slider, a cc toggle button and subtitle picker menu, etc. There is currently no consistent way to control HTML 5 media elements without using a mouse. 

I suggest that the specs provide a way for a web component to declare whether it has a focusable sub-DOM, which should be the default for <video> and <audio> sub-DOMs, and probably some input types like date and color.
Comment 1 James Craig 2013-11-20 20:15:58 UTC
I noticed that Léonie added the accessibility keywords, so I just wanted to clarify that this not an assistive technology issue, as ATs like screen readers don't have problems navigating into and out of shadow DOM components. 

This bug is about the fact that a general keyboard user cannot control complex shadow DOM components, including a number of the "native" implementations of HTML5 form controls. HTML should not force people to use a mouse or other pointer device, regardless if their reason is an accessibility need, personal preference, or general usability decision.
Comment 2 Hayato Ito 2013-11-26 00:38:12 UTC
I think the issue is related to focus navigation.
http://w3c.github.io/webcomponents/spec/shadow/#focus-navigation

But I am afraid that I don't understand what the proposal is.

> I suggest that the specs provide a way for a web component to declare whether it has a focusable sub-DOM, which should be the default for <video> and <audio> sub-DOMs, and probably some input types like date and color.

I appreciate if you could you clarify this part.
Comment 3 James Craig 2013-12-02 19:00:57 UTC
(In reply to Hayato Ito from comment #2)
> I think the issue is related to focus navigation.
> http://w3c.github.io/webcomponents/spec/shadow/#focus-navigation
> 
> But I am afraid that I don't understand what the proposal is.
> 
> > I suggest that the specs provide a way for a web component to declare whether it has a focusable sub-DOM, which should be the default for <video> and <audio> sub-DOMs, and probably some input types like date and color.
> 
> I appreciate if you could you clarify this part.

In the following example, I would expect subsequent presses of the Tab key to move focus through #tabstop1, #tabstop2, #tabstop3, #tabstop4, and #tabstop5. into and out of the shadow DOM, because those controls are navigable and not otherwise controllable via the keyboard.

<button id="tabstop1">A button *before* the video element</button>
<video src="movie.m4v">
  <shadow-root id="video-shadow-root">
    <button id="tabstop2">Play/pause</button>
    <button id="tabstop3">Toggle captions</button>
    <button id="tabstop4">Mute</button>
  </shadow-root>
</video>
<button id="tabstop5">A button *after* the video element</button>


I would expect focus to only land on the <input type="text"> sub-DOM element, because the shadow DOM author already included the functionality for the increment/decrement buttons as keyboard event handlers on the UP and DOWN arrow keys. Giving those elements a tab stop would be redundant for keyboard users. 

It's possible this can be achieved using existing tabindex syntax to mark sub-DOM elements as focusable or non-focusable using an explicit tabindex of 0 or -1, or falling back to the elements "focusability" default. E.g. input fields are focusable, most everything else is not, unless overridden with tabindex="0"

<button id="tabstop1">A button *before* the input element</button>
<input type="number">
  <shadow-root id="video-shadow-root">
    <input type="text">
    <!-- b/c the functions of the next two elements are already handled by UP/DOWN arrow key events on the text input, these next two are focusable, so the shadow DOM only gets one tab stop (#tabstop2). (Could be specified using tabindex like so.) -->
    <button aria-label="increment" tabindex="-1">+</button>
    <button aria-label="decrement" tabindex="-1">-</button>
  </shadow-root>
</input>
<button id="tabstop3">A button *after* the input element</button>

The UA should determine how many tab stops a shadow DOM has, and change the Tab key behavior accordingly. During one of these shadow DOM focus change events, the document.activeElement should remain the same, but the shadow DOM activeElement should change. 

Tangent:

It's possible the Event object's relatedTarget property should be updated as well. If the current press of the Tab key does not change the main document.activeElement (b/c focus is moving to another sub-DOM element), should Event.target and Event.relatedTarget point to the same element? It seems to me that KeyboardEvent.relatedTarget should only point to an different element if focus will move there assuming the author does not call preventDefault().

For example, if focus is on #tabstop1, pressing the Tab key will trigger keyboard blur and focus events where Event.target and Event.relatedTarget both point to the video#target element. However, if focus is on #tabstop4, pressing the Tab key will trigger keyboard blur and focus events where Event.target is video#target, and Event.relatedTarget if button#tabstop5. 

<button id="tabstop1">A button *before* the video element</button>
<video src="movie.m4v" id="target">
  <shadow-root id="video-shadow-root">
    <button id="tabstop2">Play/pause</button>
    <button id="tabstop3">Toggle captions</button>
    <button id="tabstop4">Mute</button>
  </shadow-root>
</video>
<button id="tabstop5">A button *after* the video element</button>
Comment 4 James Craig 2013-12-02 19:03:52 UTC
(In reply to James Craig from comment #3)

> <button id="tabstop1">A button *before* the input element</button>
> <input type="number">
>   <shadow-root id="video-shadow-root">
>     <input type="text">
>     <!-- b/c the functions of the next two elements are already handled by
> UP/DOWN arrow key events on the text input, these next two are focusable, so
> the shadow DOM only gets one tab stop (#tabstop2). (Could be specified using
> tabindex like so.) -->
>     <button aria-label="increment" tabindex="-1">+</button>
>     <button aria-label="decrement" tabindex="-1">-</button>
>   </shadow-root>
> </input>
> <button id="tabstop3">A button *after* the input element</button>

I left off the referenced ID. 

  <input type="text">

Should be:

  <input type="text" id="tabstop2">
Comment 5 Silvia Pfeiffer 2014-01-30 23:22:37 UTC
It seems to me that http://w3c.github.io/webcomponents/spec/shadow/#focus-navigation addresses this now. Can we close this bug?
Comment 6 James Craig 2014-01-31 00:39:08 UTC
The only lacking part I see now is that the spec does not address how a parent document can prevent the focusability of elements inside a shadow DOM. For example, shadow DOM implementations of <input type="date"> will likely include several focusable elements (a popup dialog with menus, buttons, etc), whether natively focusable or by adding tabindex="0". If an author explicitly disallows focusability on the element by one of these methods:

<input type="date" disabled>
<input type="date" tabindex="-1">

...then I believe the sub-level shadow DOM elements should inherit the non-focusability of the shadow host.
Comment 7 Charles McCathieNevile 2015-06-12 14:53:00 UTC
Needs to be copied across to Github and Shadow DOM
Comment 8 Charles McCathieNevile 2016-04-11 14:26:35 UTC
Moved, and then fixed… see https://github.com/w3c/webcomponents/issues/375