<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:base="en">
	<title>alice&#39;s blog</title>
	<subtitle>Igalian blog.</subtitle>
	<link href="https://blogs.igalia.com/alice/feed/feed.xml" rel="self"/>
	<link href="https://blogs.igalia.com/alice/alice/"/>
	<updated>2026-01-30T00:00:00Z</updated>
	<id>https://blogs.igalia.com/alice/</id>
	<author>
		<name>Alice Boxhall</name>
		<email>alice@igalia.com</email>
	</author>
	
	<entry>
		<title>Reference Target: having your encapsulation and eating it too</title>
		<link href="https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/"/>
		<updated>2026-01-30T00:00:00Z</updated>
		<id>https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/</id>
		<content type="html">&lt;p&gt;Three years ago, I wrote a blog post about &lt;a href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;How Shadow DOM and accessibility are in conflict&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I explained how the encapsulation provided by shadow roots is a double-edged sword, particularly when it comes to accessibility. Being able to programmatically express relationships from one element to another is critical for creating user experiences which don’t rely on visual cues - but elements inside a shadow root aren’t available to be referenced from elements in the light DOM. This encapsulation, however, is what allows component authors to create accessible components which can be safely reused in any context, without necessarily requiring any particular dependencies or extra build steps.&lt;/p&gt;
&lt;p&gt;In the year or so following, even more heroic attempts were made to square this circle, and finally one seems likely to stick: &lt;a href=&quot;https://github.com/WICG/webcomponents/blob/gh-pages/proposals/reference-target-explainer.md&quot;&gt;Reference Target&lt;/a&gt;. In this post I’ll explain how this feature works, why I like it, and what the situation is right now with the spec and implementation (thanks in part to &lt;a href=&quot;https://blogs.igalia.com/mrego/solving-cross-root-aria-issues-in-shadow-dom/&quot;&gt;Igalia’s NLNet funding&lt;/a&gt;).&lt;/p&gt;
&lt;h2 id=&quot;a-quick-introduction&quot; tabindex=&quot;-1&quot;&gt;A quick introduction &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;referenceTarget&lt;/code&gt; is a new property on shadow root objects which lets you nominate an element in the shadow root’s subtree which should be the &lt;strong&gt;target&lt;/strong&gt; of any attribute-based &lt;strong&gt;reference&lt;/strong&gt; to the shadow host.&lt;/p&gt;
&lt;p&gt;As an example, imagine that you have a &lt;code&gt;&amp;lt;custom-input&amp;gt;&lt;/code&gt; component, which has an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; tucked away in its shadow root.
This is a pattern which is ubiqutous in custom element libraries, as it allows the custom element to use &lt;a href=&quot;https://en.wikipedia.org/wiki/Object_composition&quot;&gt;composition&lt;/a&gt; to enhance the behaviour of a built-in element.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;track&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Track name:&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;track&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  #shadowRoot&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;inner-input&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can set the shadow root’s &lt;code&gt;referenceTarget&lt;/code&gt; to allow the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; to correctly label the inner &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// in the constructor for the custom-input:&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; shadowRoot &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attachShadow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;open&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;shadowRoot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;referenceTarget &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;inner-input&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;shadowRoot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;innerHTML &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &#39;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;input id&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;inner-input&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;`&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This lets the label refer to the &lt;code&gt;&amp;lt;custom-input&amp;gt;&lt;/code&gt; just like it would refer to an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;; the &lt;code&gt;&amp;lt;custom-input&amp;gt;&lt;/code&gt; transparently proxies the reference through to the encapsulated &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;!--
bk: would it be more accurate to say &quot;This makes the `&lt;custom-input&gt;` act as a transparent proxy for its internal input for the purposes of the `&lt;label&gt;`&quot;?  It&#39;s a little easier for me to grok because the above easily misreads to me as &quot;behave just like&quot;, but not necessarily &quot;behave as if it were&quot; - if that makes any sense

ab: is this better?
--&gt;
&lt;p&gt;In this example, we’ve set the &lt;code&gt;referenceTarget&lt;/code&gt; property directly on the &lt;code&gt;ShadowRoot&lt;/code&gt; object, but it can also be set declaratively when using the &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt; element to create the shadow root:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;track&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Track name:&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;track&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;template&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;shadowRootMode&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;open&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;token attr-name&quot;&gt;shadowRootReferenceTarget&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;inner-input&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;inner-input&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works equally well for &lt;em&gt;any&lt;/em&gt; attribute which refers to other elements like this - even if you set it via a reflected property like &lt;code&gt;commandForElement&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;settings-trigger&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Site settings&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-dialog&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;settings-dialog&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  #shadowRoot referenceTarget=&quot;inner-dialog&quot;&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dialog&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;inner-dialog&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;close&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-label&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;close&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token attr-name&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token attr-name&quot;&gt;commandFor&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;inner-dialog&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token attr-name&quot;&gt;|&lt;/span&gt;           &lt;span class=&quot;token attr-name&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;request-close&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;fieldset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;legend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Colour scheme:&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;legend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;dark&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;radio&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;dark&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;appearance&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;dark&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;checked&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;      Dark&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- TODO: more colour schemes --&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;fieldset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-dialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Someone probably has a good reason why they&#39;d do it this way, right?&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; settingsButton &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;settings-trigger&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;settingsButton&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;command &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;show-modal&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;settingsButton&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;commandForElement &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;settings-dialog&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This lets the &lt;code&gt;&amp;lt;custom-dialog&amp;gt;&lt;/code&gt; behave exactly like a &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; for the purposes of the &lt;code&gt;command&lt;/code&gt; and &lt;code&gt;commandForElement&lt;/code&gt; properties.&lt;/p&gt;
&lt;h2 id=&quot;why-i-like-it&quot; tabindex=&quot;-1&quot;&gt;Why I like it &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In my &lt;a href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;earlier blog post&lt;/a&gt; I explained that I was concerned that the Cross-root ARIA delegation and reflection proposals introduced a &lt;a href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/#limitations-of-these-apis&quot;&gt;bottleneck problem&lt;/a&gt;. This problem arose because it was only possible to refer to one element per attribute, rather than allowing &lt;em&gt;arbitrary&lt;/em&gt; cross-shadow root references.&lt;/p&gt;
&lt;p&gt;This proposal &lt;em&gt;absolutely doesn’t&lt;/em&gt; solve that problem, but it reframes the overall problem such that I don’t think it matters any more.&lt;/p&gt;
&lt;p&gt;The key difference between reference target and the earlier proposals is that reference target is a catch-all for references to the shadow host, rather than requiring each attribute to be forwarded separately. This solves a specific problem, which I alluded to above: how can custom element authors encapsulate the behaviour of a given built-in HTML element while also allowing other elements to refer to the custom element as if it &lt;em&gt;was&lt;/em&gt; the built-in element?&lt;/p&gt;
&lt;p&gt;I believe this more narrow problem definition accounts for a significant proportion - not all, but many - cases where references need to be able to cross into shadow roots. And it makes the API make much more sense to me - if you’re using the &lt;code&gt;for&lt;/code&gt; attribute to refer to a &lt;code&gt;&amp;lt;custom-input&amp;gt;&lt;/code&gt;, you’re not meant to need to know that you’re actually referring to an enclosed &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, you just want the &lt;code&gt;&amp;lt;custom-input&amp;gt;&lt;/code&gt; to be labelled. This API makes the enclosed &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; an implementation detail. And since a shadow root can only have one host, it makes sense that it can only have one reference target.&lt;/p&gt;
&lt;h2 id=&quot;adjacent-as-yet-unsolved-problems&quot; tabindex=&quot;-1&quot;&gt;Adjacent, as-yet unsolved problems &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;arbitrary-cross-shadow-root-references&quot; tabindex=&quot;-1&quot;&gt;Arbitrary cross-shadow root references &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As mentioned above, one adjacent problem is the problem of element references which do need to refer to specific elements within a shadow root, rather than a stand-in for the shadow host.&lt;/p&gt;
&lt;p&gt;The explainer gives two examples of this: &lt;a href=&quot;https://github.com/WICG/webcomponents/blob/gh-pages/proposals/reference-target-explainer.md#aria-activedescendant-and-comboboxes&quot;&gt;&lt;code&gt;aria-activedescendant&lt;/code&gt;&lt;/a&gt; on a combobox element which needs to refer to an option inside of a shadow root, and ARIA attributes like &lt;code&gt;aria-labelledby&lt;/code&gt;, &lt;code&gt;aria-describedby&lt;/code&gt; and &lt;code&gt;aria-errormessage&lt;/code&gt; which may need &lt;a href=&quot;https://github.com/WICG/webcomponents/blob/gh-pages/proposals/reference-target-explainer.md#fine-grained-aria-labelledby-and-aria-describedby&quot;&gt;a computed name for the component which excludes some parts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I think we need to be careful about generalising this problem, though. As I describe later in the explainer, I think we might be able to &lt;a href=&quot;https://github.com/WICG/webcomponents/blob/gh-pages/proposals/reference-target-explainer.md#addressing-individual-use-cases-separately&quot;&gt;get better solutions by solving more specific problems&lt;/a&gt; - as we have with reference target.&lt;/p&gt;
&lt;p&gt;If you have another example of where you need to refer to specific elements within a shadow root, you can leave a comment on &lt;a href=&quot;https://github.com/WICG/webcomponents/issues/1111&quot;&gt;this issue collecting use cases&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;attribute-forwarding&quot; tabindex=&quot;-1&quot;&gt;Attribute forwarding &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;While reference target allows other elements to refer to the encapsulated element, custom element authors may also want to allow developers using their component to use standard HTML and ARIA attributes on the host element and have those apply to the encapsulated element.&lt;/p&gt;
&lt;p&gt;For example, you might like to support &lt;code&gt;popoverTarget&lt;/code&gt; on your &lt;code&gt;&amp;lt;custom-button&amp;gt;&lt;/code&gt; element:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;popoverTarget&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;languages&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Language&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-menu&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;languages&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;popover&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-menuitem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Nederlands&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-menuitem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-menuitem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Fryslân&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-menuitem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-menuitem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Vlaams&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-menuitem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-menu&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is an &lt;a href=&quot;https://github.com/WICG/webcomponents/issues/1068&quot;&gt;issue for the attribute forwarding idea&lt;/a&gt;; leave a comment there if this is an idea you’d like to see pursued.&lt;/p&gt;
&lt;h3 id=&quot;form-association&quot; tabindex=&quot;-1&quot;&gt;Form association &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Custom elements can be specified as &lt;a href=&quot;https://html.spec.whatwg.org/dev/custom-elements.html#custom-elements-face-example&quot;&gt;form-associated&lt;/a&gt;, but there’s no way to associate an encapsulated form-associated built-in element (such as &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;) with an enclosing &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For example, the &lt;code&gt;&amp;lt;custom-input&amp;gt;&lt;/code&gt; above could be nested in a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element, but the enclosed &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; wouldn’t be associated with the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; - instead, you’d have to use &lt;code&gt;setFormValue()&lt;/code&gt; on the custom element and copy the value of the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;spec-and-implementation-status&quot; tabindex=&quot;-1&quot;&gt;Spec and implementation status &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In brief: the spec changes seem to be in good shape, Chromium has the most feature-complete implementation and there are significantly less-baked implementations in WebKit and Firefox.&lt;/p&gt;
&lt;h3 id=&quot;spec-changes&quot; tabindex=&quot;-1&quot;&gt;Spec changes &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There are open pull requests on the &lt;a href=&quot;https://github.com/whatwg/html/pull/10995&quot;&gt;HTML&lt;/a&gt; and &lt;a href=&quot;https://github.com/whatwg/dom/pull/1353&quot;&gt;DOM&lt;/a&gt; specs. Since these PRs are still being reviewed, the concepts and terminology below might change, but this is what we have right now. These changes have already had a few rounds of reviews, thanks to Anne van Kesteren, Olli Pettay and Keith Cirkel.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://whatpr.org/dom/1353/388779b...64676d6.html&quot;&gt;DOM&lt;/a&gt; change:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;adds the concept of a &lt;a href=&quot;https://whatpr.org/dom/1353/388779b...64676d6.html#shadowroot-reference-target&quot;&gt;reference target&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;adds the &lt;a href=&quot;https://whatpr.org/dom/1353/388779b...64676d6.html#interface-shadowroot&quot;&gt;&lt;code&gt;referenceTarget&lt;/code&gt;&lt;/a&gt; property to the &lt;code&gt;ShadowRoot&lt;/code&gt; object.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/whatwg/html/pull/10995&quot;&gt;HTML&lt;/a&gt; change is where the actual effect of the reference target is defined.&lt;/p&gt;
&lt;h4 id=&quot;element-reference-attribute-type&quot; tabindex=&quot;-1&quot;&gt;Element reference attribute type &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;One key change in the HTML spec is the addition of an attribute type for &lt;a href=&quot;https://whatpr.org/html/10995/common-microsyntaxes.html#element-reference-attributes&quot;&gt;“element reference” attributes&lt;/a&gt;. This formalises in HTML what has previously been referred to as an &lt;a href=&quot;https://www.w3.org/TR/wai-aria/#valuetype_idref&quot;&gt;ID reference&lt;/a&gt; or &lt;a href=&quot;https://www.w3.org/TR/xmlschema11-2/#IDREF&quot;&gt;IDREF&lt;/a&gt;. This term isn’t currently used in HTML, and since the addition of &lt;a href=&quot;https://html.spec.whatwg.org/#reflecting-content-attributes-in-idl-attributes:element&quot;&gt;reflected IDL Element attributes&lt;/a&gt;, IDs aren’t strictly necessary, either.&lt;/p&gt;
&lt;p&gt;Before this change, whenever an attribute in the HTML spec was required to match another element based on its ID, this was written out explicitly where the attribute was defined. For example, the &lt;a href=&quot;https://html.spec.whatwg.org/#attr-label-for&quot;&gt;definition of the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; element’s &lt;code&gt;for&lt;/code&gt; attribute&lt;/a&gt;
currently reads:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;for&lt;/code&gt; attribute may be specified to indicate a form control with which the caption is to be associated. If the attribute is specified, the attribute’s value must be the ID of a labelable element in the same tree as the &lt;code&gt;label&lt;/code&gt; element. If the attribute is specified and there is an element in the tree whose ID is equal to the value of the for attribute, and the first such element in tree order is a labelable element, then that element is the &lt;code&gt;label&lt;/code&gt; element’s labeled control.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since reference target affects how this type of reference works, and is intended to apply for every attribute which refers to another element, it was simpler to have one central definition.&lt;/p&gt;
&lt;h4 id=&quot;reference-target-resolution&quot; tabindex=&quot;-1&quot;&gt;Reference target resolution &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;For a reference target to actually do something, we need to define what effect it has. This is defined, quite straightforwardly, in the &lt;a href=&quot;https://whatpr.org/html/10995/common-microsyntaxes.html#resolve-the-reference-target&quot;&gt;steps to resolve the reference target&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;If &lt;em&gt;element&lt;/em&gt; is not a shadow host, or &lt;em&gt;element&lt;/em&gt;’s shadow root’s reference target is null, then return &lt;em&gt;element&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Let &lt;em&gt;referenceTargetValue&lt;/em&gt; be the value of &lt;em&gt;element&lt;/em&gt;’s shadow root’s reference target.&lt;/li&gt;
&lt;li&gt;Let &lt;em&gt;candidate&lt;/em&gt; be the first element in &lt;em&gt;element&lt;/em&gt;’s shadow root whose ID matches &lt;em&gt;referenceTargetValue&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;If no such element exists, return null.&lt;/li&gt;
&lt;li&gt;Return the result of resolving the reference target on &lt;em&gt;candidate&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;These steps are recursive: if a shadow root’s reference target has its own shadow root, and that shadow root has a reference target, we keep descending into the nested shadow root.&lt;/p&gt;
&lt;p&gt;One slightly subtle design choice here is that if a shadow root has a reference target which doesn’t refer to &lt;em&gt;any&lt;/em&gt; element - for example, an empty string, or a value which doesn’t match the ID of any element in its subtree - the resolved reference target is null, &lt;strong&gt;not&lt;/strong&gt; the shadow host.&lt;/p&gt;
&lt;p&gt;For example, if you tried to use &lt;code&gt;popoverTarget&lt;/code&gt; to refer to a shadow host which had a &lt;code&gt;popover&lt;/code&gt; attribute, but had an invalid reference target on its shadow root, the &lt;code&gt;popoverTarget&lt;/code&gt; attribute won’t actually target anything:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;more-actions&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;popoverTarget&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;actions-popover&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-label&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;more actions&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;…&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Even though this has a popover attribute, the button won&#39;t toggle it! --&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-popover&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;actions-popover&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;popover&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;template&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;shadowRootMode&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;open&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;token attr-name&quot;&gt;shadowRootReferenceTarget&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;0xDEADBEEF&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;help-im-trapped-in-a-shadow-root&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;popover&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-dialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;resolved-and-unresolved-attr-target-elements&quot; tabindex=&quot;-1&quot;&gt;Resolved and unresolved &lt;em&gt;attr&lt;/em&gt; target elements &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Like many spec concepts, this one is a real mouthful.&lt;/p&gt;
&lt;p&gt;This lets us be very clear about whether reference target resolution has happened when we’re talking about what element an attribute refers to.&lt;/p&gt;
&lt;p&gt;If we’re &lt;a href=&quot;https://whatpr.org/html/10995/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes:element&quot;&gt;reflecting an attribute to its IDL counterpart&lt;/a&gt;, we now use the &lt;a href=&quot;https://whatpr.org/html/10995/common-microsyntaxes.html#get-the-unresolved-attr-target-element&quot;&gt;unresolved &lt;em&gt;attr&lt;/em&gt; target element&lt;/a&gt;. For example, if we had the DOM defined in the previous example, and we wanted to get the &lt;code&gt;popoverTargetElement&lt;/code&gt; for the &lt;code&gt;&amp;quot;settings-trigger&amp;quot;&lt;/code&gt; button:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; moreActions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;more-actions&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span class=&quot;token comment&quot;&gt;// This will log the &amp;lt;custom-popover&gt; element (!)&lt;/span&gt;&lt;br&gt;console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;moreActions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;popoverTargetElement&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(In spec terms: the &lt;code&gt;&amp;lt;custom-popover&amp;gt;&lt;/code&gt; element is the &lt;strong&gt;unresolved &lt;code&gt;popoverTarget&lt;/code&gt; target element&lt;/strong&gt; for the &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;This might also be a bit surprising; we spent quite a bit of time going back and forth on this, since we thought developers might want to know that the &lt;code&gt;popoverTarget&lt;/code&gt; isn’t actually targeting anything. However, using the unresolved target lets us have a very close parallel between setting and getting the &lt;code&gt;popoverTargetElement&lt;/code&gt;, as well as preserving the shadow root’s encapsulation.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://whatpr.org/html/10995/common-microsyntaxes.html#get-the-resolved-attr-target-element&quot;&gt;resolved &lt;em&gt;attr&lt;/em&gt; target element&lt;/a&gt;, meanwhile, is what will be used when actually doing something with the attribute - such as triggering a popover, or computing a label’s labeled control, or determining an element’s &lt;a href=&quot;https://w3c.github.io/accname/#mapping_additional_nd_description&quot;&gt;accessible description&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the above example, the &lt;strong&gt;resolved &lt;code&gt;popoverTarget&lt;/code&gt; target element&lt;/strong&gt; for the button is null. And, going back to the examples we’ve seen earlier:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;strong&gt;resolved &lt;code&gt;commandFor&lt;/code&gt; target element&lt;/strong&gt; for the Settings button is the inner &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; - clicking the button will open the &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;resolved &lt;code&gt;for&lt;/code&gt; target element&lt;/strong&gt; for the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; is the inner &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; - clicking the label will focus the input, and the input’s computed &lt;a href=&quot;https://w3c.github.io/accname/#mapping_additional_nd_name&quot;&gt;accessible name&lt;/a&gt; will be “Track name”.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;referring-to&quot; tabindex=&quot;-1&quot;&gt;“Referring to” &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;For convenience, we define the concept of an attribute &lt;a href=&quot;https://whatpr.org/html/10995/common-microsyntaxes.html#single-element-reference-refers-to&quot;&gt;“referring to”&lt;/a&gt; an element:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A single-element reference attribute &lt;em&gt;attr&lt;/em&gt; on an element &lt;em&gt;X&lt;/em&gt; &lt;strong&gt;refers to&lt;/strong&gt; an element &lt;em&gt;Y&lt;/em&gt; as its target if &lt;em&gt;Y&lt;/em&gt; is the resolved &lt;em&gt;attr&lt;/em&gt; target element for &lt;em&gt;X&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, for example, the &lt;code&gt;commandFor&lt;/code&gt; attribute on the Settings button &lt;strong&gt;refers to&lt;/strong&gt; the inner &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; element.&lt;/p&gt;
&lt;h4 id=&quot;sets-of-element-references&quot; tabindex=&quot;-1&quot;&gt;Sets of element references &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;All of the above used single element references as examples, but there are attributes which can refer to more than one element. For example, almost all of the ARIA attributes which refer to other elements refer to multiple elements in an ordered list - one such is &lt;a href=&quot;https://w3c.github.io/aria/#aria-errormessage&quot;&gt;&lt;code&gt;aria-errormessage&lt;/code&gt;&lt;/a&gt;, which can refer to one or more elements which should be exposed as specifically as an error message for an element which is marked as invalid.&lt;/p&gt;
&lt;p&gt;We define a &lt;a href=&quot;https://whatpr.org/html/10995/common-microsyntaxes.html#set-of-element-references&quot;&gt;set of element references&lt;/a&gt; attribute type, as well as a couple of subtypes which impose constraints such as ordering or uniqueness, as well as what it means for one of these attributes to &lt;strong&gt;refer to&lt;/strong&gt; another element, and how to get the resolved and unresolved &lt;em&gt;attr&lt;/em&gt; target elements for these attributes.&lt;/p&gt;
&lt;p&gt;While these are slightly more complex than the single element versions, they follow the same basic logic. The only marginally significant difference is that since they produce lists of elements, if a shadow root’s reference target is invalid, no element is added to the list for that unresolved &lt;em&gt;attr&lt;/em&gt; target, instead of returning null.&lt;/p&gt;
&lt;h4 id=&quot;using-these-concepts-in-the-rest-of-the-spec&quot; tabindex=&quot;-1&quot;&gt;Using these concepts in the rest of the spec &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Now that we’ve defined these spec concepts, we have to update each place in the spec where we previously used the “whose ID is equal to the value of the blahblah attribute” wording.&lt;/p&gt;
&lt;p&gt;Returning to our good friend &lt;code&gt;popoverTarget&lt;/code&gt;, we can see a relatively straightforward example.&lt;/p&gt;
&lt;p&gt;The definition of the &lt;code&gt;popoverTarget&lt;/code&gt; attribute now reads:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If specified, the &lt;code&gt;popovertarget&lt;/code&gt; attribute value must be a valid single-element reference attribute referring to an element with the &lt;code&gt;popover&lt;/code&gt; attribute.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And now, &lt;a href=&quot;https://whatpr.org/html/10995/59931bd...99765dc/popover.html#popover-target-element&quot;&gt;get the &lt;strong&gt;popover target element&lt;/strong&gt;&lt;/a&gt; determines &lt;em&gt;popoverElement&lt;/em&gt; like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Let &lt;em&gt;popoverElement&lt;/em&gt; be &lt;em&gt;node&lt;/em&gt;’s resolved &lt;code&gt;popovertarget&lt;/code&gt; target element.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://whatpr.org/html/10995/forms.html#labeled-control&quot;&gt;&lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; association&lt;/a&gt; is a bit more complex, since we wanted descendants of the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; to be correctly labelled when using reference target:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To determine a &lt;code&gt;label&lt;/code&gt; element &lt;em&gt;label&lt;/em&gt;’s &lt;strong&gt;labeled control&lt;/strong&gt;, run these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If &lt;em&gt;label&lt;/em&gt;’s &lt;code&gt;for&lt;/code&gt; attribute is specified, then:
&lt;ol&gt;
&lt;li&gt;If the resolved &lt;code&gt;for&lt;/code&gt; target element is not null, and the resolved &lt;code&gt;for&lt;/code&gt; target element is a labelable element, return that element.&lt;/li&gt;
&lt;li&gt;Otherwise, return null.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;For each descendant &lt;em&gt;descendant&lt;/em&gt; of &lt;em&gt;label&lt;/em&gt; in tree order:
&lt;ol&gt;
&lt;li&gt;Let &lt;em&gt;candidate&lt;/em&gt; be the result of resolving the reference target on descendant.&lt;/li&gt;
&lt;li&gt;If &lt;em&gt;candidate&lt;/em&gt; is a labelable element, return &lt;em&gt;candidate&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Return null.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;There is also a &lt;a href=&quot;https://github.com/w3c/aria/pull/2474&quot;&gt;PR open on the ARIA spec&lt;/a&gt; to introduce this terminology there.&lt;/p&gt;
&lt;h3 id=&quot;implementation-status&quot; tabindex=&quot;-1&quot;&gt;Implementation status &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/reference-target-having-your-encapsulation-and-eating-it-too/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Chromium has the &lt;a href=&quot;https://wpt.fyi/results/shadow-dom/reference-target/tentative?label=master&amp;amp;label=experimental&amp;amp;product=chrome&amp;amp;product=edge&amp;amp;aligned&quot;&gt;most complete implementation&lt;/a&gt;, though it may not quite be up to date with the latest spec changes. Any developers wanting to try it out should get the latest build of Chrome or Edge and flip on the Experimental Web Platform Features flag. If you do try it out, I’d love to hear any &lt;a href=&quot;https://github.com/WICG/webcomponents/issues/1120&quot;&gt;feedback&lt;/a&gt; you might have!&lt;/p&gt;
&lt;p&gt;WebKit and Firefox &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=1952585&quot;&gt;(tracking bug)&lt;/a&gt; each have a prototype implementation, available behind respective feature flags (&lt;code&gt;ShadowRootReferenceTargetEnabled&lt;/code&gt; for WebKit and &lt;code&gt;dom.shadowdom.referenceTarget.enabled&lt;/code&gt; for Firefox), which should pass at least most of the existing WPT tests - however, the WPT tests are insufficient to test &lt;em&gt;all&lt;/em&gt; of the functionality, and the functionality which couldn’t be tested via WPTs hasn’t been implemented yet in these engines. The Chromium implementation included adding many Chromium-specific tests for the behaviour which can’t be tested via WPTs, as well as implementing that behaviour.&lt;/p&gt;
&lt;p&gt;Currently, WPT tests can only test the computed accessible name and computed accessible role for an element, as well as testing DOM methods and user actions like clicking. However, reference target impacts the accessibility tree in many ways - not only via ARIA attributes, but via &lt;a href=&quot;https://www.w3.org/TR/html-aam-1.0/#att-popovertarget&quot;&gt;attributes like &lt;code&gt;popoverTarget&lt;/code&gt; being exposed in the accessibility tree&lt;/a&gt; as an accessible relation.&lt;/p&gt;
&lt;p&gt;And, importantly, &lt;em&gt;changes&lt;/em&gt; to the accessibility tree can require certain notifications to be fired to assistive technology APIs - and reference target introduces several new ways to change the accessibility tree. Adding, changing, or removing a shadow root’s &lt;code&gt;referenceTarget&lt;/code&gt; may cause changes in the resolved target elements for attributes, causing accessibility tree changes and potentially requiring notifications. Likewise, inserting an element with an ID which matches a shadow root’s &lt;code&gt;referenceTarget&lt;/code&gt; could also cause a shadow host’s resolved reference target to change, also potentially causing the accessibility tree to change.&lt;/p&gt;
&lt;p&gt;There are two complementary projects currently underway which will allow us to write much richer tests for accessibility tree functionality in browsers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/web-platform-tests/wpt/pull/53733&quot;&gt;support for writing WPT tests which directly test what browsers expose to accessibility APIs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/web-platform-tests/wpt/pull/55784&quot;&gt;support for an “accessible properties” API&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once we can write WPT tests which actually test the full spectrum of expected behaviour for reference target, we’ll be able to actually make it an &lt;a href=&quot;https://github.com/web-platform-tests/interop/issues/1011&quot;&gt;official interop focus area&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The prototype implementation work in WebKit and Firefox, as well as the spec work done by Igalia, was generously funded by a &lt;a href=&quot;https://blogs.igalia.com/mrego/solving-cross-root-aria-issues-in-shadow-dom/&quot;&gt;grant from NLNet Foundation&lt;/a&gt;, while the implementation work in Chromium and much of the remainder of the spec work was done by Microsoft engineers on the Edge team.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>How Shadow DOM and accessibility are in conflict</title>
		<link href="https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/"/>
		<updated>2023-02-22T00:00:00Z</updated>
		<id>https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/</id>
		<content type="html">&lt;p&gt;Shadow DOM allows web developers to create and use components which encapsulate their internals. Like encapsulation in any other programming context, being able to hide the implementation details of an HTML component has many benefits to both developers using the component in their web pages, and the developers who author and maintain the component. However, there is one major way that, to date, Shadow DOM’s encapsulation mechanism is in conflict with techniques authors use to provide an accessible user experience.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM&quot;&gt;Shadow DOM&lt;/a&gt; encapsulation essentially makes children of a shadow root “private” to any siblings or ancestors of the shadow host. This means that any HTML feature which creates a relationship &lt;em&gt;between&lt;/em&gt; elements can’t work when a relationship needs to be expressed between an element within a shadow root and one outside of it.&lt;/p&gt;
&lt;p&gt;This has some technical reasons; in particular, element IDs are scoped within a shadow root, so a reference from outside of shadow root can’t refer to an element with that ID inside a shadow root. However, it’s also a logical quandary: if the elements inside the shadow root are implementation details which are intentionally opaque from the point of view of any code outside the component, how can they also be a part of a semantic association mediated by code?&lt;/p&gt;
&lt;h2 id=&quot;semantic-relationships-and-accessibility&quot; tabindex=&quot;-1&quot;&gt;Semantic relationships and accessibility &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;What does it mean for an element to have a semantic relationship with another element?&lt;/p&gt;
&lt;p&gt;Probably the most easily familiar example of a semantic association between one element and another is the relationship between an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; and a &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;. By either placing the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;  between the opening and closing tags of the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;, or using the &lt;code&gt;for&lt;/code&gt; attribute on the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; element pointing to the ID of the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; element, we can express that there is a relationship between the two elements. The &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; provides a label for the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, and the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; is &lt;em&gt;labelled by&lt;/em&gt; [1] the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; .&lt;/p&gt;
&lt;p&gt;The association between an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; and a &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; makes absolutely no difference to how those elements are rendered. If I put a &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; (or even just some text) right next to an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, a user who can see both will easily intuit that the label text is associated with the input field. And the label also makes no difference to what data is submitted with the associated &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;By creating the semantic association, essentially what we’re doing is &lt;em&gt;explicitly expressing&lt;/em&gt; in code what is &lt;em&gt;implicitly expressed&lt;/em&gt; by the way the elements relate to each other visually.&lt;/p&gt;
&lt;p&gt;In the case of &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, we do get a nice little bonus in that it makes the entire contents of the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; a click/tap target for the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;. So if you’re labelling a checkbox, for example, you’re making it easier for users of pointer-based devices (i.e. most users) to actually use the checkbox itself.&lt;/p&gt;
&lt;p&gt;A less easily appreciated effect of creating a semantic relationship between &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; is the way it affects the experience of Assistive Technogy (AT) users. Assistive technologies are software and hardware tools which can augment a user experience to meet the needs of people with certain disabilities.&lt;/p&gt;
&lt;p&gt;For example, a blind person might use a &lt;a href=&quot;https://en.wikipedia.org/wiki/Refreshable_braille_display&quot;&gt;refreshable braille display&lt;/a&gt; which consumes information about an application’s user interface via an assistive technology API. The braille display can display a single line of text (sometimes up to 80 characters, but more often 20-40), and the user interface the user is interacting with needs to be expressed in a textual way in order for it to be useful to them.&lt;/p&gt;
&lt;p&gt;This is achieved by generating a textual, descriptive representation of a particular UI element. So, for example, if we have the following HTML:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;agree&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;I agree&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;agree&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;checkbox&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;- then a braille display might allow a user to interact with it when it has keyboard focus by displaying a braille version of the string &lt;code&gt;I agree (x) tck bx&lt;/code&gt;. This concisely expresses three critical things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the check box’s label (“I agree”), which gives the user an indication of the upshot of the checkbox being checked or not;&lt;/li&gt;
&lt;li&gt;the check box’s state (“(x)” - i.e. checked); and&lt;/li&gt;
&lt;li&gt;the check box’s role (“tck bx” i.e. “tick box”), which gives the user an idea of what types of interactions are possible (i.e. checking or un-checking, which will indicate whether the user agrees or not).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this case, the label of the checkbox can reliably be part of the textual representation &lt;em&gt;because&lt;/em&gt; of the semantic association between the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; and the &lt;code&gt;&amp;lt;input type=&amp;quot;checkbox&amp;quot;&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;semantic-relationships-and-shadow-dom&quot; tabindex=&quot;-1&quot;&gt;Semantic relationships and Shadow DOM &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For more complicated custom elements, the types of relationships expressed go beyond a &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;/&lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; relationship. In these cases, ARIA attributes provide a larger vocabulary of relationships which can be expressed.&lt;/p&gt;
&lt;p&gt;An &lt;a href=&quot;https://www.w3.org/WAI/ARIA/apg/example-index/combobox/combobox-autocomplete-list.html&quot;&gt;accessible combobox&lt;/a&gt; involves a number of ARIA relationship attributes. It’s a good example of the type of complex component that can take a lot of subtle work to get right, making it a good candidate for a reusable component [2].&lt;/p&gt;
&lt;p&gt;One way this might look with Shadow DOM is that the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; might be tucked away inside a shadow root with some logic, extra elements for presentation, and so on, while the autocomplete options might be provided by the author of the page.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- I&#39;ll use #shadowRoot and #/shadowroot to denote the beginning and end of&lt;br&gt;     the shadow root node, and | (vertical bars) to indicate which nodes are&lt;br&gt;     within the shadow root. --&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-autocomplete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  #shadowRoot&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;innerInput&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;combobox&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-autocomplete&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token attr-name&quot;&gt;|&lt;/span&gt;        &lt;span class=&quot;token attr-name&quot;&gt;aria-expanded&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;false&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-controls&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;autocompleteOptions&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;listbox&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;autocompleteOptions&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |     &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- author-provided options will be slotted in here --&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  #/shadowRoot&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Cassowary&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt2&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Currawong&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt3&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Emu&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt4&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Ibis&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt5&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Magpie&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-autocomplete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From the point of view of the author using the &lt;code&gt;&amp;lt;custom-autocomplete&amp;gt;&lt;/code&gt; this is a pretty good deal: they give it a set of &lt;code&gt;&amp;lt;custom-option&amp;gt;&lt;/code&gt;s and the logic encapsulated within the component creates an accessible, encapsulated autocomplete widget with those options.&lt;/p&gt;
&lt;p&gt;Well, with a few caveats.&lt;/p&gt;
&lt;h3 id=&quot;referring-from-shadow-dom-outwards&quot; tabindex=&quot;-1&quot;&gt;Referring from Shadow DOM outwards &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When a user is interacting with the autocomplete component, keyboard focus will be on the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; element, so the user can start typing the name of the option they’re interested in. When the user wants to select an option from the list, they may use the arrow keys to quickly select the option they’re interested in. The currently selected option will be visually indicated, but keyboard focus remains in the text field so that the user can keep typing and refine the options further.&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://blogs.igalia.com/alice/img/a8LzccKv2w-398.avif 398w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://blogs.igalia.com/alice/img/a8LzccKv2w-398.webp 398w&quot;&gt;&lt;img alt=&quot;a screenshot of the Google search box with the text &#39;combobox html&#39; followed by an insertion caret, and autocomplete options beginning &#39;combobox tkinter&#39;, &#39;combobox c#&#39;, &#39;combobox html&#39;, with &#39;combobox html&#39; highlighted&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://blogs.igalia.com/alice/img/a8LzccKv2w-398.png&quot; width=&quot;398&quot; height=&quot;260&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;For AT users, we need to ensure that the AT is aware that an option is “active”, so that it can display it to the user in the most appropriate way (such as showing its text on the single line of a braille display), without moving keyboard focus off the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The ARIA attribute which achieves this is &lt;code&gt;aria-activedescendant&lt;/code&gt;. Like the &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;‘s &lt;code&gt;for&lt;/code&gt;’, it creates an association between two elements via the ID of the element being referred to; for example:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- this is an extra-simplified example! --&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;combobox&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-expanded&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-activedescendant&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;option2&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;listbox&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;option&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;option1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Hawksbill&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;option&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;option2&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Leatherback&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;option&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;option3&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Loggerhead&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So, in this case, when keyboard focus is on the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, the AT will place its “virtual cursor” [3] on the second option, showing the user that option in the appropriate manner while allowing the user to continue typing.&lt;/p&gt;
&lt;p&gt;If you’re familiar with Shadow DOM, or you read the introduction to this article carefully, you can probably see where this falls apart with the Shadow DOM example above:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-autocomplete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  #shadowRoot&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;innerInput&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;combobox&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-autocomplete&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token attr-name&quot;&gt;|&lt;/span&gt;        &lt;span class=&quot;token attr-name&quot;&gt;aria-expanded&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-controls&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;autocompleteOptions&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token attr-name&quot;&gt;|&lt;/span&gt;        &lt;span class=&quot;token attr-name&quot;&gt;aria-activedescendant&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;?????&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;listbox&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;autocompleteOptions&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |     &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- author-provided options will be slotted in here --&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  #/shadowRoot&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Cassowary&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt2&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Currawong&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt3&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Emu&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt4&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Ibis&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt5&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Magpie&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-autocomplete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, even though the &lt;code&gt;&amp;lt;custom-option&amp;gt;&lt;/code&gt; is outside the shadow root and thus not part of any encapsulation guarantees, those very encapsulation guarantees prevent the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; from referring to any of the &lt;code&gt;&amp;lt;custom-option&amp;gt;&lt;/code&gt;s, because the shadow root creates a new &lt;a href=&quot;https://dom.spec.whatwg.org/#shadow-trees&quot;&gt;tree&lt;/a&gt;. Because of this, the IDs of the &lt;code&gt;&amp;lt;custom-option&amp;gt;&lt;/code&gt;s aren’t “visible” from within the shadow root, so there’s no value for the &lt;code&gt;aria-activedescendant&lt;/code&gt; attribute that could refer to one of them.&lt;/p&gt;
&lt;p&gt;There is one option available (&lt;a href=&quot;https://wpt.fyi/results/html/dom/aria-element-reflection.html&quot;&gt;not yet universally&lt;/a&gt;) to the author of the &lt;code&gt;&amp;lt;custom-autocomplete&amp;gt;&lt;/code&gt;: using the &lt;a href=&quot;https://w3c.github.io/aria/#ARIAMixin&quot;&gt;&lt;code&gt;ariaActiveDescendantElement&lt;/code&gt;&lt;/a&gt; IDL attribute:&lt;/p&gt;
&lt;pre class=&quot;language-js&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;innerInput&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ariaActiveDescendantElement &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; slot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assignedNodes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works where the ID fails, because an &lt;a href=&quot;https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes:element&quot;&gt;IDL attribute with type &lt;code&gt;Element&lt;/code&gt;&lt;/a&gt; can refer to any element that is a descendant of any “shadow-including ancestor” of the element hosting the attribute.&lt;/p&gt;
&lt;p&gt;If you haven’t had the misfortune of becoming familiar with the way the HTML spec expresses tree-related concepts, what this means in this example is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;&amp;lt;custom-autocomplete&amp;gt;&lt;/code&gt; element is a &lt;em&gt;shadow-including ancestor&lt;/em&gt; of the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, even though it’s not considered an &lt;em&gt;ancestor&lt;/em&gt; because the shadow root is considered the root of its own tree;&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;&amp;lt;custom-option&amp;gt;&lt;/code&gt;s are all &lt;em&gt;descendants&lt;/em&gt; of the &lt;code&gt;&amp;lt;custom-autocomplete&amp;gt;&lt;/code&gt; (while the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; is only a &lt;em&gt;shadow-including descendant&lt;/em&gt;);&lt;/li&gt;
&lt;li&gt;so, the &lt;code&gt;&amp;lt;custom-options&amp;gt;&lt;/code&gt; may be referred to from the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; (but not the reverse).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, while this doesn’t yet work everywhere, it offers at least a partial solution to this one part of the problem.&lt;/p&gt;
&lt;h3 id=&quot;referring-into-shadow-dom&quot; tabindex=&quot;-1&quot;&gt;Referring into Shadow DOM &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The above example “works” because the &lt;code&gt;&amp;lt;custom-option&amp;gt;&lt;/code&gt;s are in the shadow root’s &lt;a href=&quot;https://dom.spec.whatwg.org/#concept-light-tree&quot;&gt;“light tree”&lt;/a&gt;. But what if the &lt;code&gt;&amp;lt;custom-autocomplete&amp;gt;&lt;/code&gt; needed to use an option list which was in another shadow root? For example, the option list might encapsulate logic to fetch autocomplete options from a server, or to use a &lt;a href=&quot;https://github.com/Flipkart/recyclerlistview&quot;&gt;recycler&lt;/a&gt; pattern to manage list items.&lt;/p&gt;
&lt;p&gt;That might look something like this:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-address-autocomplete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  #shadowRoot&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;innerInput&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;combobox&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-autocomplete&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token attr-name&quot;&gt;|&lt;/span&gt;        &lt;span class=&quot;token attr-name&quot;&gt;aria-expanded&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-controls&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;autocompleteOptions&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token attr-name&quot;&gt;|&lt;/span&gt;        &lt;span class=&quot;token attr-name&quot;&gt;aria-activedescendant&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;?????&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-recycler&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;listbox&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;autocompleteOptions&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   #shadowRoot&lt;br&gt;  |   | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt3&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;221B Baker St&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;29 Acacia Road&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt2&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;724 Evergreen Terrace&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   #/shadowRoot&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-recycler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  #/shadowRoot&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-address-autocomplete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, there is no way to create an &lt;code&gt;aria-activedescendant&lt;/code&gt; association from the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; to one of the &lt;code&gt;&amp;lt;custom-option&amp;gt;&lt;/code&gt;s. Unlike in the previous example, the &lt;code&gt;&amp;lt;custom-option&amp;gt;&lt;/code&gt;s aren’t descendants of a shadow-including ancestor of the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, so we can’t even use the &lt;code&gt;ariaActiveDescendantElement&lt;/code&gt; IDL attribute. This was a deliberate choice in the design of the &lt;a href=&quot;https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes:element&quot;&gt;reflection API&lt;/a&gt;: if authors made a reference to an element inside a shadow root available on an element outside of it, it essentially makes the encapsulation moot, particularly in the case of a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/mode&quot;&gt;closed shadow root&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;custom-option&amp;gt;&lt;/code&gt;s are effectively an implementation detail of the &lt;code&gt;&amp;lt;custom-recycler&amp;gt;&lt;/code&gt;, so logically it makes sense for them to be hidden or private from the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;. However, they are only an implementation detail as long as you don’t need to express a semantic relationship with one of them in code.&lt;/p&gt;
&lt;p&gt;To put it another way: the contents of the shadow root is private to its light tree, but &lt;em&gt;not to users&lt;/em&gt;. If a user can perceive a relationship between elements in the light tree and the shadow tree, but the author can’t express that relationship in code, then the encapsulation provided by Shadow DOM is at odds with the semantics of the page, and so at odds with accessibility. This is a conundrum for Shadow DOM.&lt;/p&gt;
&lt;h2 id=&quot;squaring-the-circle-prior-and-current-work-on-expressing-relationships-across-shadow-roots&quot; tabindex=&quot;-1&quot;&gt;Squaring the circle: prior and current work on expressing relationships across shadow roots &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There have been numerous attempts to try to address this glaring gap in Shadow DOM’s capabilities.&lt;/p&gt;
&lt;h3 id=&quot;element-idl-attribute-reflection&quot; tabindex=&quot;-1&quot;&gt;Element IDL attribute reflection &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As described above, allowing IDL attributes with type &lt;code&gt;Element&lt;/code&gt; to express relationships from elements within Shadow DOM to elements in the &lt;a href=&quot;https://dom.spec.whatwg.org/#concept-light-tree&quot;&gt;light tree&lt;/a&gt;. At the time of writing, this is implemented in WebKit (available in Safari Technology Preview) and shipping in Blink-based browsers.&lt;/p&gt;
&lt;h3 id=&quot;element-idl-attribute-reflection-to-allow-referring-into-open-shadow-roots&quot; tabindex=&quot;-1&quot;&gt;Element IDL attribute reflection to allow referring into open shadow roots &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Nolan Lawson wrote a detailed explainer and &lt;a href=&quot;https://gist.github.com/nolanlawson/4fe8b5d672cda3bcc4daf58079145202&quot;&gt;proposal&lt;/a&gt; that Element IDL references should be permitted to refer into open shadow roots.&lt;/p&gt;
&lt;p&gt;This idea has been floated several times, and the push-back tends to be along the lines that even the relatively weaker encapsulation guarantees of open shadow roots would be violated by an API of this form. For example, it would allow a non-Shadow DOM aware script to accidentally traverse into a shadow root’s children.&lt;/p&gt;
&lt;p&gt;That this proposal keeps being arrived at independently, and in particular that it’s now being suggested by developers actively working with Shadow DOM, says something about the appeal - it would be straightforward to spec and implement, and would would be as easy to use as the existing IDL attributes.&lt;/p&gt;
&lt;p&gt;It might even be possible to mitigate the encapsulation issues, potentially via something like &lt;a href=&quot;https://dom.spec.whatwg.org/#retarget&quot;&gt;retargeting&lt;/a&gt; as is done for event targets.&lt;/p&gt;
&lt;p&gt;Even if that could be done, there are still two major downsides with this proposal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it would leave developers using components with closed shadow roots still lacking any option to create these associations;&lt;/li&gt;
&lt;li&gt;it’s not (yet) compatible with &lt;a href=&quot;https://web.dev/declarative-shadow-dom/&quot;&gt;Declarative Shadow DOM&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;part&quot; tabindex=&quot;-1&quot;&gt;&lt;code&gt;::part()&lt;/code&gt;? &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;CSS &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/::part&quot;&gt;&lt;code&gt;::part&lt;/code&gt;&lt;/a&gt;s seem like a very closely related solution: the problem they’re solving was that developers wanted to interact with (in this case, style) elements within shadow roots. &lt;code&gt;::part&lt;/code&gt; does this in an encapsulation-preserving way, because &lt;code&gt;::part&lt;/code&gt;s can only be targeted by CSS styles,  not by &lt;code&gt;querySelector()&lt;/code&gt; which can only return (light tree) &lt;em&gt;descendants&lt;/em&gt; of the parent node.&lt;/p&gt;
&lt;p&gt;However, &lt;code&gt;::part&lt;/code&gt;s can’t be used directly for IDREF attributes without a major change to how IDREF attributes and indeed &lt;code&gt;::part&lt;/code&gt;s work, since IDREF attributes are explicitly based on the &lt;code&gt;id&lt;/code&gt; attribute of the related element, and &lt;code&gt;::part&lt;/code&gt;s are only valid for matching CSS selectors, not HTML attributes.&lt;/p&gt;
&lt;p&gt;These may be surmountable issues, but they wouldn’t be easy to address; it’s probably easier to find new solutions inspired by &lt;code&gt;::part&lt;/code&gt; instead.&lt;/p&gt;
&lt;h3 id=&quot;explicit-import-export-of-ids-to-from-shadow-roots&quot; tabindex=&quot;-1&quot;&gt;Explicit import/export of IDs to/from shadow roots &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There was an &lt;a href=&quot;https://github.com/WICG/aom/issues/169&quot;&gt;attempt to design an API&lt;/a&gt; based on &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/exportparts&quot;&gt;exportparts&lt;/a&gt;, which would allow the import/export of IDs to/from shadow roots.&lt;/p&gt;
&lt;p&gt;This had a few issues with being confusing and arduous to use, most particularly that unlike &lt;code&gt;exportparts&lt;/code&gt;, the attributes in question would be on the shadow &lt;em&gt;host&lt;/em&gt;, meaning that they needed to be added by the author &lt;em&gt;using&lt;/em&gt; the custom element, since they would need to ensure that each exported/imported ID was unique in the scope it was exported/imported to.&lt;/p&gt;
&lt;p&gt;This means it would be labour-intensive for authors to use, but also that unlike &lt;code&gt;::part&lt;/code&gt; it doesn’t have an opt-in step from the custom element; rather, any element with an ID may have its ID exported or imported using this API, regardless of the intended use or audience for the ID. Essentially, it implies that any ID becomes part of the public API for the shadow root.&lt;/p&gt;
&lt;h3 id=&quot;cross-root-aria-and-more-delegation-reflection&quot; tabindex=&quot;-1&quot;&gt;Cross-root ARIA (and more?) delegation/reflection &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;These complementary proposals (&lt;a href=&quot;https://github.com/leobalter/cross-root-aria-delegation/blob/main/explainer.md&quot;&gt;Cross-root ARIA Delegation&lt;/a&gt; and &lt;a href=&quot;https://github.com/Westbrook/cross-root-aria-reflection/&quot;&gt;Cross-root ARIA Reflection&lt;/a&gt;) add attributes which allow a custom element:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;to “delegate” ARIA attributes from a shadow host to a single element (per attribute) with the shadow root, and&lt;/li&gt;
&lt;li&gt;to “reflect” (export) a particular element (or several?) within a shadow root as the target of a relationship from an element outside the shadow root.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;cross-root-aria-delegation&quot; tabindex=&quot;-1&quot;&gt;Cross-root ARIA delegation &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Taking inspiration from &lt;a href=&quot;https://dom.spec.whatwg.org/#shadowroot-delegates-focus&quot;&gt;&lt;code&gt;delegatesFocus&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://github.com/leobalter/cross-root-aria-delegation/blob/main/explainer.md&quot;&gt;cross-root ARIA delegation&lt;/a&gt; would allow a shadow root to declare that it “delegates” certain attributes from the shadow host to specific elements within the shadow root.&lt;/p&gt;
&lt;p&gt;Taking a modified example from the explainer which uses declarative shadow DOM as an illustration:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;description&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Description&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;x-input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-label&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Name&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-describedby&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;description&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;template&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;shadowroot&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;closed&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;token attr-name&quot;&gt;shadowrootdelegatesariaattributes&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;aria-label aria-describedby&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;input&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;           &lt;span class=&quot;token attr-name&quot;&gt;delegatedariaattributes&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;aria-label aria-describedby&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;delegatedariaattributes&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;aria-label&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Another target&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;x-input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: the API proposed includes both imperative and declarative versions, but the declarative version makes for a more concise example.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This example would result in both the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; and the &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; having the &lt;code&gt;aria-label&lt;/code&gt; from the shadow host (“Name”) applied, and the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; having an &lt;code&gt;aria-describedby&lt;/code&gt; relationship with the span adjacent to the &lt;code&gt;&amp;lt;x-input&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This means that an author using the &lt;code&gt;&amp;lt;x-input&amp;gt;&lt;/code&gt; element can simply apply ARIA attributes to the shadow host exactly as they would for a regular &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; element, and have them work as expected. Furthermore, like &lt;code&gt;delegatesFocus&lt;/code&gt;, this proposal would work recursively: any number of levels of shadow roots could delegate attributes from a shadow host to the desired target for those attributes.&lt;/p&gt;
&lt;p&gt;As shown in the example above, these relationships are intended serialisable using declarative shadow DOM, via attributes on &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Furthermore, this proposal means that &lt;em&gt;author attributes&lt;/em&gt; on custom elements can be respected &lt;em&gt;without the author needing to know anything about the custom element internals&lt;/em&gt; - as long as the custom element author has correctly predicted what attributes should apply to which internal elements.&lt;/p&gt;
&lt;h4 id=&quot;cross-root-aria-reflection&quot; tabindex=&quot;-1&quot;&gt;Cross-root ARIA reflection &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Westbrook/cross-root-aria-reflection/blob/main/cross-root-aria-reflection.md&quot;&gt;Cross-root ARIA reflection&lt;/a&gt; is complementary to cross-root ARIA delegation. Essentially, it allows a custom element author to “export” elements inside of a shadow root to be available as a target for relationship attributes - much like a &lt;code&gt;::part&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Modifying an example from the explainer, once again using declarative shadow DOM:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-controls&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-activedescendent&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;x-optlist&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;template&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;shadowroot&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;open&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;token attr-name&quot;&gt;shadowrootreflectsariacontrols&lt;/span&gt;&lt;br&gt;            &lt;span class=&quot;token attr-name&quot;&gt;shadowrootreflectsariaactivedescendent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;reflectariacontrols&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;x-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;221B Baker St&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;x-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;x-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt2&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;reflectariaactivedescendant&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;29 Acacia Road&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;x-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;x-option&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;opt3&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;724 Evergreen Terrace&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;x-option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;x-foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; ends up with an &lt;code&gt;aria-controls&lt;/code&gt; relationship with the &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;, and an &lt;code&gt;aria-activedescendant&lt;/code&gt; relationship with the second &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is complementary to cross-root ARIA delegation in that it allows the creation of relationships in the opposite direction: from outside a shadow root to inside.&lt;/p&gt;
&lt;h4 id=&quot;limitations-of-these-apis&quot; tabindex=&quot;-1&quot;&gt;Limitations of these APIs &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;h5&gt;&lt;strong&gt;Bottleneck effect&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;The main limitation of these APIs is that they can only allow expressing relationships to one element or set of elements for each attribute in each direction. Effectively, it makes the shadow root a bottleneck for these types of relationships.&lt;/p&gt;
&lt;p&gt;For example, a shadow host which has an &lt;code&gt;aria-describedby&lt;/code&gt; value can create a relationship from any number of elements within its shadow root (and their shadow roots, recursively) to a &lt;em&gt;single&lt;/em&gt; list of elements in its tree. If there are multiple elements within its shadow root which all need different cross-root &lt;code&gt;aria-describedby&lt;/code&gt; values, these APIs can’t achieve that.&lt;/p&gt;
&lt;p&gt;Similarly, a shadow host may &lt;code&gt;reflect&lt;/code&gt; an element (or several) as a target for a particular attribute, but any element referring to the shadow host for that relationship will create a relationship with the same element(s).&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;custom-address&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;address&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  #shadowRoot&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;slot&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;labelforstreet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;      ⤷ &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;slot&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;labelforstreet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;?????&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Street&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;street&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-describedby&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;?????&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;slot&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;descriptionforstreet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;      ⤷ &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;slot&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;descriptionforstreet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;streetdescription&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;          The street address&lt;br&gt;        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;slot&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;labelforsuburb&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;      ⤷ &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;slot&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;labelforsuburb&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;?????&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Suburb&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;suburb&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-describedby&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;?????&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;slot&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;descriptionforsuburb&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;      ⤷ &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;slot&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;descriptionforstreet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;suburbdescription&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;          The suburb&lt;br&gt;        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  |   &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;slot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  | &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  #/shadowRoot&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;slot&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;labelforstreet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;?????&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Street&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;slot&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;descriptionforstreet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;streetdescription&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;The street address&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;slot&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;labelforsuburb&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;?????&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Suburb&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;slot&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;descriptionforstreet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;suburbdescription&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;The suburb&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;custom-address&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this extremely contrived and unlikely example, the two &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;s inside the shadow root each want different &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;s to be able to refer to them, and want to refer to different light tree elements using &lt;code&gt;aria-describedby&lt;/code&gt;. Since the delegation/reflection APIs only allow one target or set of targets for each attribute in each direction (inwards or outwards), this could not work with these APIs.&lt;/p&gt;
&lt;p&gt;However, this may not be a huge issue in practice, since custom elements tend to act somewhat “atomically” by design.&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;Proliferation of IDL attributes&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;Depending on the exact shape of the API, it may result in the addition of multiple IDL attributes &lt;em&gt;per ARIA attribute&lt;/em&gt; to certain objects.&lt;/p&gt;
&lt;p&gt;This may be fairly straightforwardly avoided, however. The proposal sketched for cross-root ARIA delegation uses token list attributes [4], for example, which means only one attribute needs to be added (plus the extra attribute on &lt;code&gt;&amp;lt;template&amp;gt;&lt;/code&gt;/&lt;code&gt;ShadowRoot&lt;/code&gt;). Similarly, the proposed &lt;a href=&quot;https://github.com/leobalter/cross-root-aria-delegation/blob/main/explainer.md#22-parts&quot;&gt;&lt;code&gt;exportfor&lt;/code&gt;&lt;/a&gt; attribute seems to be an analogous version of &lt;code&gt;reflectaria*&lt;/code&gt; which takes a token list.&lt;/p&gt;
&lt;h2 id=&quot;what-needs-to-happen-next&quot; tabindex=&quot;-1&quot;&gt;What needs to happen next? &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There is an increasing sense of urgency about these issues - arguably one that’s been missing since the inception of Shadow DOM - since Shadow DOM is hovering around a critical adoption threshold. Collectively, we’ve been arguing for almost a decade about what the optimal solution might look like, with only modest progress in the form of an API that is only now implemented in two browser engines, and not yet shipping in any.&lt;/p&gt;
&lt;p&gt;We have a number of promising proposals as to how to solve these problems, but there is still a lot of work to be done to get us to the point where we actually have solutions shipping and able to be used. We need to investigate how well these proposals follow web standard design principles, how feasible they are to ship in browsers, and how well these proposals fit the problems actually being experienced by custom element authors. We need to prototype proposals which meet these requirements, to get them in the hands of developers who can test them in the context of their actual code. And, we need to navigate the standards process and ensure that we get to the stage of having as many browser engines as possible shipping whatever APIs will meet the needs of both developers and users.&lt;/p&gt;
&lt;h2 id=&quot;thank-you&quot; tabindex=&quot;-1&quot;&gt;Thank you! &lt;a class=&quot;header-anchor&quot; href=&quot;https://blogs.igalia.com/alice/how-shadow-dom-and-accessibility-are-in-conflict/&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Thank you to &lt;a href=&quot;https://www.igalia.com/team/mrego&quot;&gt;Manuel Rego&lt;/a&gt;, &lt;a href=&quot;https://www.igalia.com/team/bkardell&quot;&gt;Brian Kardell&lt;/a&gt;, &lt;a href=&quot;https://www.igalia.com/team/emeyer&quot;&gt;Eric Meyer&lt;/a&gt; and &lt;a href=&quot;https://sarahmhigley.com/&quot;&gt;Sarah Higley&lt;/a&gt; for reading drafts of this post, providing early feedback and contributing ideas in discussions. Thank you to &lt;a href=&quot;https://westbrookjohnson.com/&quot;&gt;Westbrook Johnson&lt;/a&gt; for the recycler list example. Thank you to &lt;a href=&quot;https://www.igalia.com/team/ana&quot;&gt;Ana Rute Mendes&lt;/a&gt; for setting up this blog for me. And thank you to everyone who is still working on or has worked on this problem!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;[1] Since I’m writing this as an Australian, this is the natural way for me to spell “labelled”, but it’s also the way the corresponding ARIA attribute is spelled - much to the annoyance of anyone used to American spellings.&lt;/p&gt;
&lt;p&gt;[2] The examples shown here, and in the ARIA Authoring Practices Guide, are &lt;em&gt;not&lt;/em&gt; production-ready code, which often takes into account extra considerations over and above those discussed here.&lt;/p&gt;
&lt;p&gt;[3] The virtual cursor typically follows keyboard focus, but the user may move it themselves in order to consume non-interactive content, or the AT may move it in cases like this.&lt;/p&gt;
&lt;p&gt;[4] &lt;code&gt;&amp;lt;template shadworootdelegatesariaattributes=&amp;quot;aria-labelledby, aria-describedby&amp;quot;&amp;gt;&lt;/code&gt; rather than &lt;code&gt;&amp;lt;template shadowrootdelegatearialabelledby shadowrootdelegatesariadescribedby&amp;gt;&lt;/code&gt;&lt;/p&gt;
</content>
	</entry>
</feed>
