Making composed-tree.svg more accessible…

These are some notes on steps we took that improved the accessibility of composed-tree.svg up to its current state (at time of writing), and why each one was worth doing. Note that the order doesn't reflect what we actually did over time, so much as the order we probably should have done things.

General code cleaning

Some steps didn't have any practical impact on accessibility as far as we know, and could have been done differently. Reasons for doing them include:

Step: Simplify the code to make it easily readable. This involved:
Rationale: Since the code changes were all made manually, this made the subsequent editing and testing much easier, and in practical terms it was an essential first step.

Accessibility steps

The following steps are all things that directly enhanced the accessibility of the diagram in some way we could test:

Step: Write a description of the image in HTML
Rationale: So far, we don't know how to make the image completely accessible. And in some cases it is still not even usable at all. The description can be used as a destination for a longdesc attribute or as fallback content for an object element. We should also work out how to use it as an alternate description inside the SVG, but have not done that yet.
Step: Add a top-level title element.
Rationale: The first title element found in the document is generally used by browsers as the title of the page, in the same way as the HTML title element.
Step: Add tabindex="0" to each node in the diagram.
Rationale: This enables some basic keyboard navigation, and made the nodes part of a navigation tree, although it only works in some user agents.
Step: Reorder the source so the nodes appear in the order of walking the tree breadth-first - i.e. top node, all the second-level nodes from left to right, then all the third-level nodes, etc.
Rationale: This meant that keyboard navigation produced an order that makes some sense, which helped give some idea of the structure.
Rationale: This combines with adding tabindex attributes and reordering the source code to provide more efficient keyboard navigation of the tree. Unfortunately the links don't work properly in some browsers. In addition it is only worth doing if the tree is more than about 6 elements, since there are about three times as many focusable items to move through.
Rationale: This meant that at least VoiceOver cursor navigation became more efficient in some browsers: The cursor would move from node to node, skipping the links inside each node. This reduced the number of keystrokes to move across the tree.
Step: Provide a title element for each item in the defs element, and each navigable element (the nodes, links, and the images in the defs element.
Rationale: Screenreaders are not currently doing anything useful with this, which is basically bad implementation. Browsers do use the element to provide tooltips which can be very helpful in interpreting the graphics, and we did take advantage of this step later, so it was worth doing. Experimental tools using the title element according to the specification have been described for more than a decade so there may be more uses we don't know.
Step: Add aria list markup - role="list" and role="listitem" as appropriate to match the structure of the tree.
Rationale: This provided more information in screenreaders, and helps communicate the structure being presented.

Accessibility workarounds

Some of the things we did were to work around bugs, or deficient implementations. They should not be necessary, but in practice they are worth doing:

Step: Add aria-labelledby attributes to things that have titles
Rationale: No screenreader we tested seems to support the title element according to the SVG specification. As noted above the first title is used for the document as a whole, but others seem to be unavailable. This is a bug. Redundant aria-labelledby is an effective workaround for many browser/screenreader combinations.
Step: Embed the SVG source in HTML - composed-tree.html
Rationale: That is the only way to make IE provide useful information to the screenreader.
Step: Add aria-hidden="true" to the defs element
Rationale: This stopped some browsers, but not all, from passing the content of the defs elements to the screenreader.

Mistakes we made, bugs we found

Please note: This section still needs missing content added

There were bugs and problems on more or less every platform we tested.

No browser/screenreader combination presents the <title> of an SVG element, other than the first <title> in the document source, as an "accessible name". Similarly, no browser appears to enable access to the <desc> element, unless it is referred to by aria-describedby This is a pretty straightforward failure on something that has been in SVG since last century - perhaps the accessibility equivalent of not actually implementing the <rect> element.

Browsers

Safari

It seems the SVG is not tab-navigable unless the screen reader is running.

Without <defs aria-hidden="true"> Yandex passes the content of the <defs> element to VoiceOver

It is apparently not possible to follow a link that points to a target within an SVG document using the keyboard, even with the screen reader running. (Usual approaches like "return", "VO+space" do not work".

Yandex Browser (Mac)

Without <defs aria-hidden="true"> Yandex passes the content of the <defs> element to VoiceOver

Firefox

Even with <defs aria-hidden="true"> Firefox passes the content of the defs element to VoiceOver

Firefox doesn't appear to support tabindex="0" in SVG. It is possible for focus to get to nodes by following a link.

Firefox doesn't provide any focus indicator when navigating by keyboard.

Internet Explorer

Reportedly, IE doesn't actually show anything until the SVG is embedded as inline code in an HTML page. (Can anyone confirm or deny with more detail?)

Thanks are due to Léonie Watson for extensive help with testing, and constructive suggestions on how to resolve problems. Contributions, as pull requests or email to the SVG accessibility task force, are welcome to this document.

This document is on github - feel free to propose changes, offer information about browser support, etc.