Table of Contents generated with DocToc
- ARIA (and other) relationship attributes and Shadow DOM
- Problems
- Proposed solutions
- Some thoughts on potential refinements/alternative directions
ARIA (and other) relationship attributes and Shadow DOM
Problems
1. Currently specced APIs offer no way to refer into shadow roots.
@nolanlawson has a longer write-up of this issue here: https://gist.github.com/nolanlawson/4fe8b5d672cda3bcc4daf58079145202
It is possible to refer from an element within a shadow root to any element which is a descendant of any ancestor shadow root or document, using an IDL attribute which takes an Element or FrozenArray<Element>.
<custom-listbox> #shadowRoot | <div id="listbox" role="listbox" | aria-activedescendant> | <slot></slot> #/shadowRoot <custom-listitem>Author listitem 2</custom-listitem> <custom-listitem>Author listitem 3</custom-listitem> <custom-listitem>Author listitem 4</custom-listitem> </custom-listbox>
// refers to an element in a "lighter" tree listbox.ariaActiveDescendantElement = slot.assignedNodes()[0];
This doesn't work at all for referring into an element within a shadow root which is not a direct ancestor.
<my-label> #shadowRoot | <!-- wants to refer into custom-combobox's shadow root --> | <label for="⚠️inner-input⚠️"><slot></slot></label> #/shadowRoot Postal address: </my-label> <custom-combobox> #shadowRoot | <!-- wants to refer into custom-optionlist's shadow root --> | <input role="combobox" id="inner-input" | aria-owns="optlist" | aria-activedescendant="⚠️opt1⚠️"> | <custom-optionlist id="optlist"> | #shadowRoot | | <x-option id="opt1">221B Baker St</x-option> | | <x-option id="opt2">29 Acacia Road</x-option> | | <x-option id="opt3">724 Evergreen Terrace</x-option> | #/shadowRoot | </custom-optionlist> #/shadowRoot </custom-combobox>
It isn't even possible to refer to an element within an element's own shadow root.
2. Using Element-based IDL attributes to refer across shadow roots isn't serializable
Recall the earlier example of creating a reference from within a shadow root out to an ancestor subtree:
<custom-listbox> #shadowRoot | <div id="listbox" role="listbox" | aria-activedescendant> | <slot></slot> #/shadowRoot <custom-listitem id="item1">Author listitem 2</custom-listitem> <custom-listitem id="item2">Author listitem 3</custom-listitem> <custom-listitem id="item3">Author listitem 4</custom-listitem> </custom-listbox>
// refers to an element in a "lighter" tree listbox.ariaActiveDescendantElement = slot.assignedNodes()[0];
This does work, but can't ever be serialized, because the ID of the listbox's aria-activedescendant-associated element, "item1", isn't in the same tree as the listbox.