Skip to content

Commit

Permalink
Expand on Cross Root Aria section
Browse files Browse the repository at this point in the history
  • Loading branch information
Westbrook committed Sep 7, 2023
1 parent bd58feb commit faf6654
Showing 1 changed file with 108 additions and 55 deletions.
163 changes: 108 additions & 55 deletions reports/2023.html
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ <h3>Table of Contents</h3>
<tr>
<th><a href="#scoped-element-registries">Scoped Element Registries</a></th>
<td><a href="https://github.com/WICG/webcomponents/issues/716">WICG/webcomponents#716</a></td>
<td>Consensus</td>
<td>Consensus, lacking initial prototype</td>
</tr>
<tr>
<th><a href="#css-slot-content-detection">CSS Slot Content Detection</a></th>
Expand Down Expand Up @@ -122,97 +122,148 @@ <h3>Links</h3>
<section>
<h3>Description</h3>
<p>
Shadow boundaries prevent content on either side of the boundary from referencing each other via ID references. ID references being the basis of the majority of the accessibility patters outlines by aria attributes, this causes a major issue in developing accessible content with shadow DOM. While there are ways to develop these UIs by orchestrating the relationships between elements of synthesizing the passing of content across a shadow boundary, these practices generally position accessible development out of reach for most developers, both at component creation and component consumption time.
This problem space is expertly described by Alice Boxhall in this <a href="https://alice.pages.igalia.com/blog/how-shadow-dom-and-accessibility-are-in-conflict/" target="_blank">blog post</a>.
</p>
<p>
Developers of a custom element should be able to outline to browsers how content from outside of their shadow root realtes to the content within it and visa versa. Cross-root ARIA Delegation would allow developers to define how content on the outside is mapped to the content within a shadow root, while Cross-root ARIA Reflection would define how content within a shadow root was made available to content outside of it.
In short, accessibility with shadow roots in broken when addressed via the patterns that web developers have come to be acustomed to in their work.
</p>
</section>
<section>
<h3>Status</h3>
<p>
Implementors participating in bi-weekly Accessibility Object Model syncs with WICG have all been favorable to the delegation work and are interested in the reflection work as a tighly related API that maybe is a fast follower. Leo Balter is working on finalizing proposal text for the delegation API at which time Westbrook Johnson will apply similar teminology to the reflection API proposal.
Implementors participating in bi-weekly Accessibility Object Model meetings with at the WICG have implied
</p>
</section>
<section>
<h3>Initial API Summary/Quick API Proposal</h3>
<h4>Delegation API</h4>
<p>HTML</p>
<h3>Key Scenarios</h3>
<p>
This plays out in a Combobox pattern as follows:
</p>
<pre>
<code>
&lt;span id="foo">Description!&lt;/span>
&lt;template id="template1">
&lt;input id="input" autoarialabel autoariadescribedby />
&lt;span autoarialabel>Another target&lt;/span>
&lt;/template>
&lt;x-foo aria-label="Hello!" aria-describedby="foo">&lt;/x-foo>
&lt;x-label id="x-label">
#shadowRoot
| &lt;label for="">Example Label&lt;/label>
&lt;/x-label>
&lt;x-combobox id="x-combobox-1">
#shadowRoot
| &lt;x-input>
| #shadowRoot
| | &lt;input
| | role="combobox"
| | aria-expanded="true"
| | />
| &lt;/x-input>
| &lt;button aria-label="Open" aria-expanded="true">v&lt;/button>
|
| &lt;x-listbox id="x-listbox-1">
| #shadowRoot
| | &lt;div role="listbox">
| | &lt;div role="option">Option 1&lt;/div>
| | &lt;div role="option">Option 2&lt;/div>
| | &lt;div role="option">Option 3&lt;/div>
| | &lt;/div>
| &lt;/x-listbox>
&lt;/x-combobox>
</code>
</pre>
<p>JS</p>
<p>Even when leveraging the available aria attributes in this case there is no way to assocaite the <code>x-label</code> to the <code>x-input</code> or either of the <code>[role="listbox"]</code> or <code>[role="option"]</code> elements to it either.</p>
<p>Less complex patterns are similarly blocked by current APIs. Here we see a custom radio group:</p>
<pre>
<code>
const template = document.getElementById('template1');

class XFoo extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open", delegatesAriaLabel: true, delegatesAriaDescribedBy: true });
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
}

customElements.define("x-foo", XFoo);
&lt;div role="radiogroup">
&lt;x-button>
#shadowRoot
| &lt;button role="radio">&lt;/button>
&lt;/x-button>
&lt;x-button>
#shadowRoot
| &lt;button role="radio">&lt;/button>
&lt;/x-button>
&lt;x-button>
#shadowRoot
| &lt;button role="radio">&lt;/button>
&lt;/x-button>
&lt;/div>
</code>
</pre>
<h4>Reflection API</h4>
<p>HTML</p>
<p>Due to the shadow boundary and DOM element between the <code>[role="radio"]</code> element and the <code>[role="radiogroup"]</code> ancestor, there is no way to complete the accessibility tree that is needed to provide information about this interface to screen readers.</p>
</section>
<section>
<h3>Initial API Summary/Quick API Proposal</h3>
<p>Leveraging the Element Handles API the Combobox pattern would be work out as follows:</p>
<pre>
<code>
&lt;input aria-controlls="foo" aria-activedescendent="foo">Description!&lt;/span>
&lt;template id="template1">
&lt;ul reflectariacontrols>
&lt;li>Item 1&lt;/li>
&lt;li reflectariaactivedescendent>Item 2&lt;/li>
&lt;li>Item 3&lt;/li>
&lt;/ul&gt;
&lt;/template>
&lt;x-foo id="foo">&lt;/x-foo>
&lt;x-label id="x-label" importhandles="label-for: x-combobox-1::handle(the-input)">
#shadowRoot
| &lt;label for=":host::handle(label-for)">Example Label&lt;/label>
&lt;/x-label>
&lt;x-combobox id="x-combobox-1">
#shadowRoot
| &lt;x-input
| exporthandles="the-input"
| importhandles="my-activedescendant: x-listbox-1::handle(active), my-listbox: x-listbox-1::handle(the-listbox)">
| #shadowRoot
| | &lt;input
| | role="combobox"
| | handle="the-input"
| | aria-controls=":host::handle(my-listbox)"
| | aria-activedescendant=":host::handle(my-activedescendant)"
| | aria-expanded="true"
| | />
| &lt;/x-input>
| &lt;button aria-label="Open" aria-expanded="true">v&lt;/button>
|
| &lt;x-listbox id="x-listbox-1">
| #shadowRoot
| | &lt;div role="listbox" handle="the-listbox">
| | &lt;div role="option" handle="opt1 active">Option 1&lt;/div>
| | &lt;div role="option" handle="opt2">Option 2&lt;/div>
| | &lt;div role="option" handle="opt3">Option 3&lt;/div>
| | &lt;/div>
| &lt;/x-listbox>
&lt;/x-combobox>
</code>
</pre>
<p>JS</p>
<p>Leveraging the Aria Delegate API the radio group pattern could be acheived via:</p>
<pre>
<code>
const template = document.getElementById('template1');

class XFoo extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open", reflectsAriaControls: true, reflectsAriaActivedescendent: true });
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
}
customElements.define("x-foo", XFoo);
&lt;div role="radiogroup">
&lt;x-button role="radio">
#shadowRoot shadowrootsemanticdelegate="button"
| &lt;button id="button">&lt;/button>
&lt;/x-button>
&lt;x-button role="radio">
#shadowRoot shadowrootsemanticdelegate="button"
| &lt;button role="radio" id="button">&lt;/button>
&lt;/x-button>
&lt;x-button>
#shadowRoot shadowrootsemanticdelegate="button"
| &lt;button id="button">&lt;/button>
&lt;/x-button>
&lt;/div>
</code>
</pre>
</section>
<section>
<h3>Key Scenarios</h3>
<p>When developing many of the patterns outlines in the <a href="https://www.w3.org/WAI/ARIA/apg/patterns/" target="_blank">ARIA Authoring Practices Guide</a> having this capability would allow for encapsulating responsibilities outlined by the `role` attribute in a shadow root.</p>
</section>
<section>
<h3>Related Specs</h3>
<ul>
<li><a href="https://github.com/WICG/aom" target="_blank">AOM</a></li>
<li><a href="https://wicg.github.io/aom/aria-reflection-explainer.html" target="_blank">ARIA Reflection</a></li>
<li><a href="https://github.com/WICG/aom/blob/gh-pages/element_reference_properties.md" target="_blank">Element reference DOM properties</a></li>
<li>Import/Export IDs: <a href="https://github.com/WICG/aom/issues/169" target="_blank">Content attribute to import/export IDs across shadow boundaries WICG/aom#169</a></li>
<li>Cross Root Delegation and Reflection: <a href="https://github.com/leobalter/cross-root-aria-delegation" target="_blank">https://github.com/leobalter/cross-root-aria-delegation</a></li>
<li>Semantic Delegates: <a href="https://github.com/alice/aom/blob/gh-pages/semantic-delegate.md" target="_blank">https://github.com/alice/aom/blob/gh-pages/semantic-delegate.md</a></li>
<li>Encapsulation preserving IDL references: <a href="https://github.com/WICG/aom/issues/195" target="_blank">Encapsulation-preserving IDL Element reference attributes WICG/aom#195</a></li>
<li>Element Handles: RFC: <a href="https://github.com/WICG/aom/pull/200" target="_blank">Element Handles for Cross-root ARIA WICG/aom#200</a></li>
<li>and more, many striking nuanced grounds in between and around the above proposals</li>
</ul>
</section>
<section>
<h3>Open Questions</h3>
<ul>
<li>Should these two ideas can/should really ship separately? While the reflection API was ideated after the delegation API it may not be practical to separate them at the implementation/consumption level.</li>
<li>Is `delegation` and `reflection` the right name for these APIs? Particularly, "reflection" is used in <a href="https://wicg.github.io/aom/aria-reflection-explainer.html" target="_blank">ARIA Reflection</a>.</li>
<li>There are non-ARIA attributes that would benefit from being supported by these APIs. Should they be drafted in a more general way?</li>
<li>Which is the best way?</li>
<li>Can <em>all</em> problems be solves with one API or is the variance of issue requiring multiple APIs?</li>
</ul>
</section>
</section>
Expand All @@ -225,7 +276,9 @@ <h3>Links</h3>
<dt>Previous WCCG Report(s)</dt>
<dd>N/A</dd>
<dt>GitHub issues:</dt>
<dd>---</dd>
<dd><a href="https://github.com/w3c/csswg-drafts/issues/7922">w3c/csswg-drafts#7922</a></dd>
<dd><a href="https://github.com/WICG/webcomponents/issues/936">WICG/webcomponents#936</a></dd>
<dd><a href="https://github.com/w3c/csswg-drafts/issues/6867">w3c/csswg-drafts#6867</a></dd>
<dt>Browser positions:</dt>
<dd>---</dd>
</dl>
Expand Down

0 comments on commit faf6654

Please sign in to comment.