The canvas problem: Making a screen reader accessible HTML editor

Introduction

HTML editors have their qwirks. forever now we’ve known of the issue with multiline edits and screen readers not reading their contents because the amazing site owner decided that having a multiline edit was not enough, but they wanted to add a formatting overlay and of course they, quote unquote, forgot, to add accesibility support. But what happens when we have a canvas?

An HTML canvas is an element that is not interactable from a screen reader standpoint because it is basically a picture. A picture you can click on and the browser knows where you clicked and it can send that information somewhere, maybe via Javascript locally or to an API somewhere. A canvas with good accessibility is for example, Google Docs. GDocs is not ideal, but they are taking mostly everything into account when it comes to making the canvas accessible with screen readers.

Recently at work we are making a new editor -can’t give much detail without spoiling the surprise- and we have to come up with a way of making it accessible. So we have to be clever and come up with accessibility features for a canvas. First let’s not forget to set the role=”application” to the container, but not the entire HTML, just the iframe where the editor is located. That way the user gets entered in focus mode (or no virtual cursor) automatically. Then give the user some indication that they are in a multiline text field, maybe with an ARIA role or similar, it will all depend on your design.

I’m not going to detail everything, especially not menu bar and toolbar navigation, this has been covered a million times already. I will focus exclusively on canvas navigation and accessibility. So let’s try to break down the necessary steps:

Keyboard Navigation

Of course the canvas doesn’t have any kind of keyboard navigation unless you implement it yourself, because you are basically focused on an image. You need to provide keyboard support, and it needs to be thorough -the one thing you forget is what your users will try to use-. I will provide both keyboard usage and screen reader behaviour, so as not to repeat myself later. Also don’t forget to translate all the screen reader announcements into whatever language your editor supports.

  • Arrow key navigation: Basic left/right to navigate by characters, up/down to navigate by lines. The cursor moves, and screen reader reads out. If moving by character, it reads that character only. When moving by line it will try to read the entire line. If inside a structured view such as a table we need to announce the column/row when it changes!
  • Control + characters: Navigates by word if possible. Of course you first need to figure out word boundaries, what symbols are part of word boundaries (could be different depending on whether it’s a programming editor or a standard editor!)…
  • Shift + characters: IT serves as selection. The screen reader must indicate at all times what is being selected. If navigating way (press arrow key without shift, type, etc) the reader must announce selection cancelled or similar.
  • home/end moves to the beginning and end of line and reader announces character. Control + home and Control + end, moves to the beginning and end of the document, screen reader announces current line.
  • Typing: Google Docs makes this not configurable, and it’s annoying. I don’t want to hear every character I type, especially not with a delay (the delay is due to Google Docs getting this information from a remote API rather than locally)! so I always end up turning off live region announcements when I type and then I turn it on later. Wouldn’t it be better if I could just configure that and turn it off?
  • Structured navigation: When we come across a table, we always need to know what column/row we are in. Provide alternative shortcuts (Control + alt + arrow keys are the defacto in most screen readers). Don’t be like Google docs with Control Alt Semicolon and weird things like this I always forget. Intuitivity is also important in UX.
  • Deleting characters: There are two main behaviours. If using the delete key, the character at the cursor is deleted. Most screen readers then announce the character the cursor is at. However, when backspace is used, the character to the left is deleted and the screen reader announces the character that was deleted. This can be a bit confusing, so what macOS does (and GoogleDocs) is to place the cursor to the right/left of a character when moving around. try to experiment with different possibiltiies and see what works best for your editor. And don’t include the word “deleted” in the screen reader announcement.

Special symbols

Some screen readers have trouble announcing certain symbols when put inside an ARIA region because they are by default not spoken, so you need to provide alternative (and translated) words for them. This has to be changed only when the cursor passes over them, not when reading entire words. Some examples that come to my mind are – (dash), # (hash), or < and > (less than or greater than). This becomes much more necessary if you are working on STEM specialized software and you will need to go through each symbol to make sure that the screen reader is doing it right (and change dash for minus, maybe).

Provide a way to move the focus away from the editor

This might seem like a minor thing, but when you are a screen reader user and are used to using tab all the time to move the focus, and you see that tab is typing the tab character and you can’t get out, you have essentially a keyboard trap. Google Docs does this well (although not really documented unless you use the shortcut help dialog), with Control + alt + Shift + M. This focuses the user into the document name field, which is outside the editor.

Conclusion

I probably forgot some things. There are probably more things we are going to change and iterate over many times, but I hope that these tips help you in some way if you are creating an editor with a canvas and are lost as to how to implement accessibility.


Comments

Leave a Reply