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

leverage ShadowDOM v1 + tabindex=-1 for inertness #48

Open
valdrinkoshi opened this issue Mar 10, 2017 · 7 comments
Open

leverage ShadowDOM v1 + tabindex=-1 for inertness #48

valdrinkoshi opened this issue Mar 10, 2017 · 7 comments

Comments

@valdrinkoshi
Copy link
Collaborator

valdrinkoshi commented Mar 10, 2017

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
Copy link
Collaborator Author

valdrinkoshi commented Mar 10, 2017

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()

@robdodson
Copy link
Collaborator

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

@valdrinkoshi
Copy link
Collaborator Author

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

@robdodson
Copy link
Collaborator

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

@alice
Copy link
Member

alice commented Mar 23, 2017 via email

@robdodson
Copy link
Collaborator

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

@valdrinkoshi
Copy link
Collaborator Author

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 👌

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

No branches or pull requests

3 participants