How it works
This page explains how Accented works under the hood, why it’s designed the way it is, and what its limitations are.
Design principles
- Make the highlights stand out, but don’t break the page. It should be obvious to the developer what elements have accessibility issues. At the same time, we should make minimal changes to the DOM to ensure the page still looks and behaves as expected.
- Make it work everywhere. No matter how simple or complex the page is — whether it’s static or highly dynamic, and regardless of the HTML or CSS features used — Accented should work reliably.
- Performance matters. Developers should be able to use Accented without worrying about page slowdown. While some impact is inevitable — since axe-core runs on the main thread — we will provide tools to help measure and optimize performance. (see Improving performance).
- Accessibility matters, too. Accented has a UI of its own, and that has to be accessible. See Accessibility.
Architecture overview
Accented consists of a few core components.
- The axe-core runner.
Accented doesn’t have its own logic for detecting issues —
it delegates that to axe-core by calling
axe.run()
. - The DOM mutation observer. Accented uses a mutation observer to detect changes in the DOM and re-run the axe-core script whenever such changes happen. That way, Accented can find accessibility issues as soon as they are introduced.
- The task queue.
- Ensures that all mutations are processed correctly, even if they happen in quick succession.
- Throttles calls to the axe-core script to avoid performance issues.
- The DOM updater. This component is responsible for adding highlights (outlines, dialogs, and dialog trigger buttons) to the DOM and keeping them in sync with the page.
Known limitations
Accented aims to be as helpful and reliable as possible, but it does have limitations.
- Most importantly, no automated tool can make an application perfectly accessible, and Accented is no exception. Accented helps avoid many issues, but it’s no substitute for manual testing or usability testing with people with disabilities.
- Since Accented modifies the DOM (adding outlines, buttons, and dialogs), it can affect the results of subsequent axe-core runs — possibly causing false positives or false negatives. As you fix issues, these DOM changes are removed, reducing the chance of inaccurate results.
- Not all page changes trigger re-scans.
Accented uses a mutation observer to detect changes on the page,
but not all changes are mutations.
For example, applying a pseudo-class like
:hover
or:focus
, or toggling dark mode, may visually change the page — but won’t trigger a scan. - Some issue dialogs may not be easy to open. Accented adds a trigger button for each element with accessibility issues, and that button opens the issue dialog. There may be cases, however, when the button is hard or impossible to activate, for example, if the element is inside a container with hidden overflow, or only becomes visible on hover. In such cases, you can still view the issue details in the console.
- Accented is only as good as axe-core at accessibility testing, and axe-core itself may have bugs and flag accessibility issues unreliably. Open an issue with axe-core if you find a bug in it.
Performance
Accented is designed to minimize performance impact on the host application, but it still runs on the main thread, and some of its operations may still take hundreds of milliseconds (especially on pages with lots of elements).
The most expensive operation is running axe.run()
after a DOM mutation.
To make it as fast as possible, Accented only runs axe.run()
on the parts of the page that changed.
Accented provides APIs to help you measure and tune its performance.