Accessibility Tree: what the screen reader actually reads

A person wearing headphones is sitting in front of two monitors with colour tools – Accessibility Tree: what the screen reader reads

The accessibility tree is the most important part of your website that nobody can see. This is because a screen reader does not read your pretty pixels or your raw source code – it reads this invisible structure generated by the browser. If it is incorrect, a blind person will receive incorrect information or none at all, no matter how perfect the page looks. In this guide, I’ll show you, using real-world examples, how the accessibility tree is created, what three pieces of information each node contains, why a div styled as a button simply disappears within it, and how you can see for yourself in two minutes what a screen reader actually reads out.

What is the Accessibility Tree?

The Accessibility Tree is a data structure generated by the browser that acts as an interface between your code and assistive technology. The browser derives it from the DOM and reduces it to what matters for accessibility: the role, name, state and relationships of each control. In German, it could be called the ‘Barrierefreiheitsbaum’.

What matters is what assistive technology does with it. A screen reader, voice control or switch control does not access the visible page, but this tree specifically. It is therefore the only source from which these tools draw their information.

This leads to the central idea of this guide. Anything that is not correctly represented in the Accessibility Tree does not exist for a blind person. The visual appearance of a page is irrelevant to them – only the tree matters. That is why we always check accessibility at the level of the tree, not the design.

Who depends on a proper tree

A correctly structured accessibility tree benefits a wide range of people. This is because it is not only screen readers that rely on it; voice control and switch control systems also derive their information exclusively from this tree.

There is a wide variety of users. A blind person hears roles and names read aloud, a user with limited mobility controls the elements using voice commands, and some combine a screen magnifier with a screen reader. They all encounter the same problems as soon as the tree is incomplete.

Then there is the legal aspect. Criterion 4.1.2 ‘Name, role, value’ is a Level A requirement and therefore an absolute minimum requirement. Anyone who neglects the tree therefore fails to meet even the lowest level of the WCAG. And it is precisely this level that has been legally binding for many providers since the BFSG came into force.

DOM, accessibility tree, assistive technology: the chain

The process from code to user involves several stages. First, the browser reads the HTML and uses it to build the DOM. It then uses the DOM to calculate the accessibility tree, which contains only the information relevant to accessibility. It passes this tree on to assistive technology via an operating system interface.

At the end of this chain lies the assistive technology. The screen reader interprets the tree and tells the user what they are dealing with. It is important to note that the assistive technology communicates with the tree, not with the DOM, and certainly not with the pixels on the screen. This single insight explains why visually appealing web pages can still be inaccessible.

This distinction explains many of the barriers. A page may work technically and look good – yet still produce a fragmented tree. I go into more detail about how the DOM is structured in the guide to DOM structure.

Role, name, status: the three details for each element

Each node in the accessibility tree contains a small amount of crucial information. This tells the assistive technology what the element is, what it is called and what its state is. This is precisely what Success Criterion 4.1.2 ‘Name, Role, Value’ (Level A) requires.

InformationSignificanceExample
RoleWhat is this element?Button, link, heading, check box
NameWhat is it called?“Submit comment”
Condition / ValueIn what condition is it?activated, opened, deactivated

These details are generated in different ways. Native HTML elements provide them automatically: a<button> button automatically has the ‘button’ role, and a tick box has its state. If any of these details are missing, the assistive technology does not know what the user is looking at. And in such cases, the screen reader may say nothing at all or announce something incorrect.

How the name is determined

An element’s accessible name is not chosen randomly, but is calculated according to a fixed order. The browser checks several possible sources and selects the one with the highest priority. Knowing this order saves a lot of guesswork.

The order of precedence is clearly defined. At the very top is a aria-labelledby, followed by aaria-label , then the native reference via a label, alternative text or the visible text, and finally thetitle attribute. A aria-labeloverrides the visible label – a common pitfall when the two do not match.

It’s worth taking a closer look here. If the visible text says ‘Find out more’ aria-label but the tag says ‘Next’, a blind person will hear ‘Next’, whilst a sighted person will read ‘Find out more’. I explore where good names come from in my guide to alternative text.

Why CSS doesn’t change anything

There is one principle that surprises many developers: CSS has absolutely no effect on the accessibility tree. No matter how convincingly you style an element, its appearance does not alter what is passed on to assistive technology. The tree recognises only semantics, not visual presentation.

This has a serious consequence. An<div>element, which looks exactly like a button thanks to CSS, is still just a meaningless node in the tree, with no role and no name. To the eye, it is a button; to a screen reader, it is nothing.

It is exactly this gap between visual perception and semantics that lies at the root of many barriers. Anyone who tackles accessibility solely through design completely overlooks the tree. And it is the tree that matters.

Hidden content: what disappears from the tree

Not everything from the DOM ends up in the accessibility tree. This is because the browser specifically removes certain elements. Anything hidden using thedisplay: noneor hidden attributes does not appear in the tree at all – as far as assistive technology is concerned, it does not exist.

This can be controlled deliberately using two attributes. With aria-hidden="true", you remove an element from the tree, although it remains visible – useful, for example, for a purely decorative icon. With the presentation role, on the other hand, you simply remove an element’s semantic meaning without hiding it.

There is a common pitfall here. A aria-hidden in the wrong place hides important content from the screen reader, whilst it remains visible to the eye. Conversely, text that is visually hidden but not hidden from the screen reader remains in the tree – this is exactly how tooltips designed solely for screen readers work. In this way, an icon can be given an invisible but audible label.

The most common mistake: the ‘div’-button

Nothing illustrates the principle as clearly as the replica button. Compare a <div onclick> with a real <button>. They behave identically when clicked with the mouse, and visually they are indistinguishable.

In the Accessibility Tree, however, there is a world of difference. The actual button appears as a ‘button’ with its name, such as ‘Submit comment’. The div, on the other hand, appears as ‘generic’, with no role and no name. A screen reader simply says nothing about it, and voice control cannot activate it. For a blind person, the button is therefore invisible.

The solution is remarkably simple. Use the native element that’s already there. After all, a <button> element automatically provides a role, focusability and keyboard navigation – everything that a `div` would have to replicate laboriously and with a high risk of errors. I explain how native elements ensure keyboard navigation in the guide to keyboard navigation. The simplest code is also the most accessible.

ARIA only modifies the accessibility tree

Many people misunderstand what ARIA actually does. ARIA only modifies the accessibility tree – nothing else. It does not alter the appearance, behaviour or keyboard navigation, but only the role, name, state or attributes of an element in the tree.

This leads to the first rule of ARIA. Only use ARIA if there is no suitable native element. This is because a <button> element behaves correctly out of the box, whereas with a div enhanced using ARIA, you have to replicate this behaviour yourself using a script – including all keyboard and state logic.

Incorrect use of ARIA makes the tree worse, not better. A contradictory role or a superfluous attribute confuses the assistive technology more than it helps. I explore when ARIA is appropriate in more detail in the guide to ARIA in web applications.

Native HTML trumps recreated elements

The most reliable way to create a good tree is surprisingly simple. Use native HTML elements wherever possible. After all, each one already comes with its own correct role, state and keyboard controls – without the need for any additional code.

The list is straightforward. A <button> provides a button, a <a href> a link, a <input> (including its type) the appropriate field, and <details> with <summary> even a drop-down element. Drop-down lists and tick boxes are also available natively.

The alternative approach is laborious and prone to errors. Anyone recreating the same thing using a div with ARIA must add every role, every state and every keyboard interaction manually via script. More often than not, something gets left out, and the tree ends up being worse than the native original. That is why writing less code of your own is almost always the better choice here.

Not just screen readers: voice control too

The Accessibility Tree is not intended solely for screen readers. Voice control systems also access the same information. If a user says “Click ‘Submit comment’”, the software searches the tree for an element with the role ‘Button’ and the name ‘Submit comment’.

This makes the correct name doubly important. If the accessible name does not match the visible label, the voice control cannot find the element. The user issues a command, and nothing happens – even though the button is right in front of them.

Switch controls and other assistive technologies also rely on this tree. A correctly structured accessibility tree therefore benefits a whole range of assistive technologies at the same time. I explain how these tools work in detail in the guide to screen readers. A well-structured tree is therefore the common foundation for them all.

Dynamic content: the tree must grow with it

Nowadays, a web page rarely remains static. If the DOM changes as a result of JavaScript, the browser also updates the accessibility tree. However, assistive technology is only made aware of such changes if the appropriate events are triggered.

This is exactly where subtle errors arise. If a menu drops down without the state in the tree changing, a screen reader user will not notice this. You should therefore always keep states such as ‘expanded’ or ‘selected’ up to date, for example using aria-expanded.

The same applies to inserted messages. A new message must be actively announced, otherwise it will be overlooked (4.1.3 Status messages). The tree therefore not only reflects the initial state, but must also track every relevant change.

View the Accessibility Tree itself

You don’t have to guess what the Accessibility Tree looks like – you can view it directly.

A practical example – see what the screen reader sees: Open the Developer Tools in Chrome and switch to the ‘Accessibility’ tab. Now select any control. In the panel, you’ll see the calculated role, the accessible name along with all the sources that influence it, and the state – in other words, exactly what an assistive technology receives. Use this to check the control elements you’ve created yourself: Does your stylish button appear as a ‘Button’ with a clear name? Or does it say ‘generic’ with an empty name? In the latter case, a screen reader user will hear nothing useful when focusing on it. If you prefer an even simpler approach, use an extension such as WAVE, which makes roles and names visible directly on the page. This perspective fundamentally changes the way you view your own work.

Why overlays do not fix the tree

It is now clear why overlay widgets placed on top do not solve the problem. This is because an overlay operates on the visible interface or inserts surface-level ARIA code retrospectively. It cannot therefore generate a consistently correct accessibility tree.

The incorrect or missing roles and names remain at the core. An overlay cannot reliably deduce missing semantics because it lacks an understanding of the elements’ actual meaning. It merely masks the symptom rather than addressing the root cause. And as soon as the page changes, the whole process starts all over again.

The only reliable solution is correct code. That is precisely the underlying principle of Access Code: fixing errors where they arise – in the code, not in the visible DOM. A linter in the editor and a validation gate in the pull request ensure that the source code itself generates a clean tree.

Common errors in the Accessibility Tree

The same patterns recur time and again across many audits. These are the seven I come across most often – and they all originate in the code:

  • Interactive `div` or `span`: a generic node with no role or name.
  • Missing name: an icon button whose accessible name is left blank.
  • An incorrect role that does not correspond to the element’s function.
  • `aria-hidden` on important content, which then disappears from the tree.
  • Contradictory ARIA that overrides native semantics.
  • Name from the wrong source, such as an overridden aria-label.
  • Outdated status that no longer reflects the actual situation.

One thing stands out here. None of these errors are visible in the browser. That is precisely why they would never be noticed without looking at the tree or carrying out a test using assistive technology.

The Tree and automated testing

Automated tools can check part of the tree, but not all of it. They reliably detect when a button has no name at all or when a role is missing. This is exactly where Access Code comes in, flagging such errors right there in the editor.

However, scanners reach their limits when it comes to meaning. Whether an accessible name is truly appropriate, whether the chosen role corresponds to the function, and whether a state changes correctly in actual use cannot be assessed by machines alone. This requires human judgement.

That is why both levels are needed. The automated check handles the technical aspects, whilst the human check assesses the content. Only together do they provide the certainty that the tree is not only formally present but is also genuinely usable. At IFDB, we consistently follow this two-pronged approach.

Does your team want to fix issues in the code rather than just covering them up? In 30 minutes, we’ll explain how testing and fixing fit into your day-to-day development work.

Frequently Asked Questions about the Accessibility Tree

To round off, here are the questions I come across most frequently in my practice. The answers are brief and to the point.

Is the accessibility tree the same as the DOM?

No. Whilst the browser derives the tree from the DOM, it reduces it to the information relevant to accessibility. The DOM is for rendering, whilst the tree is for assistive technology.

Does CSS affect the accessibility tree?

No. The appearance and layout do not alter the tree. A div styled as a button remains, within it, a meaningless node with no role or name.

What is the purpose of ARIA in the Accessibility Tree?

ARIA only modifies the tree – role, name, state and attributes. It does not alter anything visually. However, native HTML elements are usually the better choice.

How to ensure your accessibility tree is correct

The process begins with the code and ends with robust validation. Access Code helps right from the development stage: a linter in the editor and a WCAG-Gate in the pull request catch incorrect roles, missing names and overridden semantics before they even go live. This ensures a clean tree structure right from the start.

Only through actual use will it become clear whether the tree is ultimately correct. Does a blind person hear the correct role and name for each element? Is every state correct? An automatic scanner alone cannot assess this. With Access Ready, we test your application with real users of assistive technology and issue a legally compliant certificate.

ApproachStarts atCorrect treeEvidence
Overlay-Widgetvisible surfacenono
Pure Scannermeasurable code errorsin partno
Access Code + Access Ready (IFDB)Source text and real-life experienceyesyes

The difference lies in the approach. An overlay simply masks the surface, whereas we fix the source. This turns ‘looks like a button’ into a genuine ‘is a button’ – in the tree that the screen reader actually reads. And so a page that merely looks accessible becomes one that is accessible at its core.

Picture of Lukas Maximilian Langer

Lukas Maximilian Langer

Als Gründer der ifdb GmbH setzt sich Lukas Maximilian Langer dafür ein, digitale Barrierefreiheit vom Pflichtthema zum Selbstverständnis zu machen. Sein Ziel: Websites, Apps und Dokumente, die für alle zugänglich sind – unabhängig von Einschränkungen.

Ihre Anfrage –
wir melden uns zeitnah zurück

Schritt 1 / 2 Anliegen

Worum geht es? Bitte mindestens eines wählen – Mehrfachauswahl möglich.