Notes on Web Components + ARIA

After listening to the Google IO  web components presentation I decided to take another look at this emerging web technology. It sort of struck me as a client side version of server side includes. Anyway I was interested in testing out an experimental implementation of web components in Chrome and to see how it plays with ARIA.

what are web components?

I am making no attempt at explaining what it is, as I would probably make a hash of it, but here is how web components is described in the Introduction to Web Components document:

The component model for the Web (also known as Web Components) consists of four pieces designed to be used together to let web application authors define widgets with a level of visual richness not possible with CSS alone, and ease of composition and reuse not possible with script libraries today.

How does use of the shadow DOM content affect ARIA use?

A potential sticking point about web components from an accessibility standpoint is that the HTML inserted into a document using web components is included in the Shadow DOM not the regular HTML DOM. I wanted to check how this affects the use of ARIA roles, states and properties.

Initial findings

Results from initial testing indicate that inclusion of ARIA roles, states and properties in content wholly inside the Shadow DOM works fine. The accessibility information is exposed correctly via the accessibility API. Screen readers can access content in the Shadow DOM without issue. There is a problem however if ARIA relationship attributes such as aria-labelledby are used on content in the regular DOM that references content in the Shadow DOM or, used on content in the shadow DOM that references content in the regular DOM.

So if an input is in the shadow DOM:

<input type="text" aria-labelledby="light">

references an element  in the regular DOM

<span id="light">regular label for text box in shadow</span>

The expected result i.e. the accessible name for the input  is the text content of the referenced element, does not happen. The labelledby relationship is broken.

Detailed tests and results page


These are only initial tests and findings based on my limited understanding of web components and experimental implementations.

To only view the results any browser will do

To test, or view content in the shadow DOM you will need:

  • Chrome with the shadow DOM experimental feature enabled.
  • To enable, put chrome://flags in the address bar and open the flags page.
  • Enable the “Shadow DOM. Mac, Windows, Linux, Chrome OS This API allows web applications to use Web Components.” flag.
  • Also useful to enable “Developer Tools experiments. Mac, Windows, Linux, Chrome OS Enable Developer Tools experiments. Use Settings panel in Developer Tools to toggle individual experiments.” flag so you can see Shadow DOM content in the developer tools. Note you have to check “show shadow DOM” in the developer tools setting as well.
  • an accessibility information inspection tool such as aViewer

Further Reading on Web Components

Categories: Technical

About Steve Faulkner

Steve was the Chief Accessibility Officer at TPGi before he left in October 2023. He joined TPGi in 2006 and was previously a Senior Web Accessibility Consultant at vision australia. Steve is a member of several groups, including the W3C Web Platforms Working Group and the W3C ARIA Working Group. He is an editor of several specifications at the W3C including ARIA in HTML and HTML Accessibility API Mappings 1.0. He also develops and maintains HTML5accessibility and the JAWS bug tracker/standards support.


Hi Steve! Awesome post, keep them coming.

The reason why labelled-by (or described-by, or any ARIA property that takes an ID reference) will not work — at least in this case — is by design: the functional encapsulation boundary makes sure that ids in the document tree and any shadow DOM trees do not collide:

Thinking in terms of encapsulation, a shadow DOM subtree is just an implementation detail for the document tree: the document tree shouldn’t have any implied knowledge of the structure of the shadow DOM tree (or vice versa). Otherwise, the opportunity for tight coupling becomes too tempting and thus renders the whole notion of functional encapsulation irrelevant.

In other words, the encapsulation abstraction functions perfectly! 🙂

Steve Faulkner says:

HI Dimitri, thanks for the clarification, I suspected that the behavior may have been by design after reading through web components docs.