inert icon indicating copy to clipboard operation
inert copied to clipboard

leverage ShadowDOM v1 + tabindex=-1 for inertness

Open valdrinkoshi opened this issue 8 years ago • 7 comments

From step 3 of https://w3c.github.io/webcomponents/spec/shadow/#sequential-focus-navigation

[...] an element whose tabindex value is negative must not be appended to NAVIGATION-ORDER.

Which in other words means that if an element has tabindex=-1 and a shadowRoot, the focus won't be able to reach the element's contents (distributed or not) 🎉

The inert polyfill could leverage this behavior for a faster performance, e.g. just set the tabindex to elements that have a shadowRoot w/o traversing them.

Another (more invasive) way to achieve inertness is to set a shadow root to the top element to be inerted, without traversing its content, e.g.

el.setAttribute('tabindex', -1);
if (!el.shadowRoot && el.attachShadow) {
  el.attachShadow({mode: 'open'}).appendChild(document.createElement('slot'));
}

Update: it is still possible to programmatically focus the content (e.g. el.querySelector('button').focus()), so we might still need to traverse the content to override focus

@alice @robdodson WDYT?

valdrinkoshi avatar Mar 10 '17 00:03 valdrinkoshi

Tested in STP and Chrome and it works 🎉 http://jsbin.com/lizipoq/2/edit?html,output Notice how focus is returned to the right place if any element within a shadow root steals focus programmatically through focus()

valdrinkoshi avatar Mar 10 '17 01:03 valdrinkoshi

sounds like a great idea to me. @valdrinkoshi do you have any interest in putting together a PR for it?

robdodson avatar Mar 21 '17 13:03 robdodson

sure i can give it a shot. Tangential note: I'm wondering if we should drop completely the support of WebComponents v0...

valdrinkoshi avatar Mar 22 '17 00:03 valdrinkoshi

hm... I think I'm cool with dropping v0. @alice wdyt?

robdodson avatar Mar 23 '17 02:03 robdodson

Works for me - it's no longer implemented anywhere, right?

On Thu, Mar 23, 2017 at 1:28 PM, Rob Dodson [email protected] wrote:

hm... I think I'm cool with dropping v0. @alice https://github.com/alice wdyt?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/WICG/inert/issues/48#issuecomment-288598951, or mute the thread https://github.com/notifications/unsubscribe-auth/AAFz6NymIgNNwIaZDzAJRJ7vgcJhnFAXks5rodjCgaJpZM4MYzbZ .

alice avatar Mar 23 '17 02:03 alice

ehhhh.... it's in Chrome and will be for quite some time...

robdodson avatar Mar 23 '17 03:03 robdodson

Yeah, and that makes things harder, as we can't know if a shadowRoot was generated via Element.createShadowRoot() (v0) or Element.attachShadow() (v1) http://jsbin.com/tenobar/1/edit?html,output We could assume that if the shadowRoot has a <content> element that's a v0 shadowRoot, but some shadowRoots don't have distribution elements at all. Also, we can't "cleanly" recognize if we are in a polyfilled ShadowDOM (e.g. we would have to check for window.ShadyDOM to support the shadydom polyfill, or other checks for other polyfills).

Apart of this problem, even if we focus only on shadowDOM v1 in chrome, we have the following challenges:

  1. we still have to override focus() for elements inside a shadowRoot in order to avoid scrolling from happening (e.g. see this example http://jsbin.com/hohegoj/4/edit?html,output) - this means we don't save much because we have to traverse the tree. We can avoid this by overriding the HTMLElement.prototype.focus where we could check if the node is inert or inside an inert parent.
  2. what to do if a rootElement doesn't have a shadowRoot? If we attachShadow, we prevent other people from doing so.

Will try to deliver something on the basis that ShadowDOM v1 is natively supported, and see how good/bad it is compared to what we have currently 👌

valdrinkoshi avatar Mar 23 '17 17:03 valdrinkoshi