Max Design

Published:

A quick note before we begin:

The “End-to-end browser and accessibility event architecture” article, along with the architectural diagram, describe all the systems that exist inside the browser, accessibility pipeline, and assistive technologies. It’s a map of the components.

This article is different — it shows the processes that flow through those systems when a user clicks an accordion button.

These flows are not linear. Events jump between multiple layers (JavaScript, Web APIs, rendering, accessibility trees, OS APIs, and assistive technologies).

That’s simply how the architecture works: it is an intricate, concurrent set of systems that constantly talk to each other.

So don’t expect a neat step-by-step “path” — expect a dance that moves across different layers.


An accordion button

Imagine a screen reader user encounters a button used to toggle an accordion open and closed.

In the closed state, the markup will be:

<button aria-label="Open accordion" aria-expanded="false">
</button>

When the button is triggered, the markup will change to:

<button aria-label="Open accordion" aria-expanded="true">
</button>

This is important as the button will then be announced as either “collapsed” or “expanded”.

How the accordion is toggled

In this example, a small piece of JavaScript is attached to the button. When the user clicks it, an event handler runs.

This code listens for the click and updates the DOM by toggling aria-expanded between "false" and "true".

The browser will run this script later in the flow.

Let’s review the entire process from start to finish.


The process

1. User interacts with the button

The browser begins with the HTML and ARIA shown above, which define the button’s role, name and state.

The button has just been clicked!

No JavaScript runs yet — the browser simply has a semantic, labelled button, which sets the foundation for everything that follows.

2. Browser computes the click target and synthesises a click event

The operating system sends low-level input events — such as pointerdown, mouseup, or pointermove — to the browser.

The browser performs hit-testing 1 to determine which on-screen element was targeted.

Based on this sequence of low-level events, the browser synthesises a DOM click event so it has a standard way to represent the interaction.

The event object contains information such as event type, target element, coordinates, and whether the event should bubble 2.

3. The click event enters the task queue

The browser does not run your script immediately.

Instead, it schedules a “dispatch click event” task 3 and places it into the Task Queue 4.

The task will run when the JavaScript engine is idle and ready for the next piece of work.

4. The event loop hands the click task to the JavaScript engine

When the event loop 5 is ready for a new task, it selects the “dispatch click event” task and hands it to the JavaScript engine.

5. The event handler runs

The browser’s event dispatch algorithm determines which element should receive the event.

The browser then runs any event listeners on that element and its ancestors. Your event handler runs and updates the DOM — in this case, toggling aria-expanded="true".

This DOM mutation 6 may cause style recalculation or layout updates.

When the handler finishes, JavaScript execution ends and control returns to the browser.

6. Browser updates style, layout, or paint if needed

The browser may update style, layout, or paint after the DOM change — either immediately or during the next rendering phase.

This may involve recalculating styles, updating layout, and repainting changes on screen.

Note: These updates do not always happen immediately. The browser may batch, defer, or skip work depending on performance optimisations.

7. Browser updates the accessibility tree

The browser updates its internal AXTree (accessibility tree) to reflect the button’s new state.

This includes recomputing accessibility properties — such as name, role, and the updated aria-expanded="true" value.

Note: AXTree updates can occur during or shortly after DOM and layout updates, depending on the engine’s scheduling.

8. Browser fires accessibility events

The accessibility subsystem determines what changed and generates one or more AXEvents — internal accessibility notifications such as “expanded state changed”.

These AXEvents are delivered through the operating system’s accessibility API.

9. Events cross the OS accessibility API boundary

The browser sends these AXEvents to the operating system’s accessibility API, such as:

The OS accessibility API notifies assistive technologies, which may also request additional information from the browser.

10. Screen reader receives events and queues utterances

The screen reader gets the notification. It then decides what to announce based on user settings.

The message is added to its internal speech queue 7. This queue manages things like order, interruptions, and priority.

It then outputs speech or braille.

The user hears: “Open accordion. Expanded.”

The process is now complete.


Caveats and nuances


Footnotes