Select to view content in your preferred language

Automated accessibility scanning and the Shadow DOM

336
0
3 weeks ago
KlaraSchmitt
Esri Regular Contributor
7 0 336


With the increased focus on improving the accessibility of software and websites, automated scanning tools have become an essential part of accessibility testing. However, not every error flagged by these tools is valid and it can sometimes be difficult to tell—especially if the Shadow DOM is involved.

Let's start with the DOM


Before explaining the Shadow DOM, it helps to first understand the DOM (Document Object Model), which is also sometimes referred to as the Light DOM.

Websites and web apps are built with HTML (Hyper Text Markup Language), which helps browsers understand a page’s structure and content. However, HTML is not interactive. While HTML supports basic functionality like linking between pages, more complex interactions—such as searching a website, viewing a popup error message, or clicking a button to play a video—require a scripting language like JavaScript.

The DOM translates the content of an HTML page into a type of object that JavaScript can understand. This allows JavaScript to dynamically change the structure, style, and content of the page.

Web Components


Web Components allow developers to create custom components as reusable blocks of code, using both the Light DOM and Shadow DOM. Each component self-contains everything it needs to work, which includes its visual styling and interactivity.

The core benefits of Web Components are: 1) Scalability, 2) Consistency, and 3) Encapsulation.

Because Web Components are a web standard, they can be used with any frontend framework. This makes them easier to reuse across projects.

As a result, teams can build and update interfaces more quickly while maintaining a consistent look and behavior for those using their websites or apps.

Grid of components in Calcite Design SystemGrid of components in Calcite Design System

The Shadow DOM


The Shadow DOM is a built‑in part of Web Components. It provides developers with a private section of the page structure that acts as a container for a component’s behavior and visual styling. This helps encapsulate, or protect, the component from changes made to the rest of the HTML on the page.

An important aspect of custom elements is encapsulation, because a custom element, by definition, is a piece of reusable functionality: it might be dropped into any web page and be expected to work. So it's important that code running in the page should not be able to accidentally break a custom element by modifying its internal implementation. Shadow DOM enables you to attach a DOM tree to an element, and have the internals of this tree hidden from JavaScript and CSS running in the page. — “Using shadow DOM” by Mozilla Contributors, licensed under CC-BY-SA 2.5

This encapsulation is what makes Web Components harder to break and easier to maintain. However, it also means that applications reusing Web Components cannot change the underlying code inside the Shadow DOM themselves.

Okay...But how does this relate to accessibility testing?


Accessibility scanning tools look for relationships in the code, such as labels, names, and roles. These relationships are used as signals to determine whether content is likely to work correctly with assistive technologies.

However, not all scanning tools can fully inspect the Shadow DOM. As of 02.01.2024, WAVE was reported as not catching errors in the Shadow DOM and their Chrome extension changelog doesn't mention Shadow DOM support. This can result in false negatives.

Other tools, like Axe (version 3.0 and later), do support the Shadow DOM. Even so, this doesn't guarantee that the tool can always determine whether a solution implemented inside the Shadow DOM is properly exposed to assistive technologies in the Light DOM.

Example: Date Range Picker


Calcite's Input Date Picker is a Web Component that can be configured as a date range picker. It combines two Input Text Web Components with a Date Picker Web Component, creating a single component involving multiple elements. Each of these pieces contains its own Shadow DOM.

Label followed by two side-by-side text input fields, each featuring a calendar icon and MM/DD/YYYY placeholder textLabel followed by two side-by-side text input fields, each featuring a calendar icon and MM/DD/YYYY placeholder text

The Input Text fields have accessible names: aria-labels for "Start Date" and "End Date". These are defined inside the Shadow DOM and cannot be modified by applications that use the component.

However, regardless of the application where this component may be used, a screen reader user will always hear those labels.

Figure: Voice Over, a Mac OS screen reader, is focused on the first text field in a date modified search results filter. The gray dialog visually displays what is being heard. This includes the label Start Date, the placeholder text MM/DD/YYYY and the type of input field, which is editable text.Figure: Voice Over, a Mac OS screen reader, is focused on the first text field in a date modified search results filter. The gray dialog visually displays what is being heard. This includes the label Start Date, the placeholder text MM/DD/YYYY and the type of input field, which is editable text.

Figure: Voice Over, a Mac OS screen reader, is focused on the second text field in a date modified search results filter. The gray dialog visually displays what is being heard. This includes the label End Date, the placeholder text MM/DD/YYYY, and the type of input field, which is editable text.Figure: Voice Over, a Mac OS screen reader, is focused on the second text field in a date modified search results filter. The gray dialog visually displays what is being heard. This includes the label End Date, the placeholder text MM/DD/YYYY, and the type of input field, which is editable text.

Figure: Calcite Date Picker with developer tools expanded to highlight the HTML text input, which contains an aria-label of Start Date. The HTML text input is within the Shadow DOM (or shadow-root) of the <calcite-input-text> component, which is a customized version of a Web Component.Figure: Calcite Date Picker with developer tools expanded to highlight the HTML text input, which contains an aria-label of Start Date. The HTML text input is within the Shadow DOM (or shadow-root) of the <calcite-input-text> component, which is a customized version of a Web Component.

The Calcite Date Picker component also provides a label property. This property allows applications to configure content inside Calcite’s Shadow DOM and it is rendered as an aria-label on a group that wraps the Date Range Picker to offer more context to the end-user.

Figure: Voice Over, a Mac OS screen reader, is focused on a group role wrapped around both the Start and End date fields. The gray dialog visually displays what is being heard. The group has a non-visible aria-label of Choose date range.Figure: Voice Over, a Mac OS screen reader, is focused on a group role wrapped around both the Start and End date fields. The gray dialog visually displays what is being heard. The group has a non-visible aria-label of Choose date range.

Figure: Calcite Date Picker with developer tools expanded. The code highlights the group role wrapped around the Calcite Input Text component <calcite-input-text>, which provides applications with a customizable aria-label within the Shadow DOM of Calcite’s parent Web Component <calcite-input-date-picker>. Because the Date Picker is made of multiple elements, there are two levels of Shadow DOM involved.Figure: Calcite Date Picker with developer tools expanded. The code highlights the group role wrapped around the Calcite Input Text component <calcite-input-text>, which provides applications with a customizable aria-label within the Shadow DOM of Calcite’s parent Web Component <calcite-input-date-picker>. Because the Date Picker is made of multiple elements, there are two levels of Shadow DOM involved.

Despite the presence of three labels—the group label, and the field labels for both text inputs—Axe reports Date Range Picker as missing a label. This is because the root component <calcite-input-date-picker> that displays in the Light DOM doesn’t appear to have a label. In reality, it has three labels, they are just lower down in the Shadow DOM. If testing this component with a screen reader, one will hear all three labels, meaning this error does not affect the user-experience.

This is an example of a false positive.

How can you identify what's in the Shadow DOM?


When inspecting an element in a browser‘s developer tools, look for a line labelled #shadow-root (open) or #shadow-root (closed). If present, then that element contains content within the Shadow DOM.

HTML code highlighting #shadow-root in the calcite-input-text componentHTML code highlighting #shadow-root in the calcite-input-text component

How do you identify false positives?


An error flagged within the Shadow DOM does not automatically mean the error is invalid. It simply means the issue requires manual verification.

Use a screen reader to interact with the component:

  • Are labels and instructions announced?
  • Are state changes communicated?

If the answer is yes, then the user experience is most likely not impacted and the reported issue is probably a false positive.

Reporting issues


If you believe an issue is still valid after manual testing, we encourage you to report it through Esri Technical Support.

Contributors
About the Author
Principal Accessibility Engineer at Esri, passionate about design, ux, accessibility, and web apps.