Firefox 70, released in October, contains a new feature called the Protection Report. It contains a graph of all the things Firefox protected you from in the last seven days. Here’s how I made that screen reader accessible.
Originally, the data shown in the protection report was only presented visually. Well, for sighted people, that is still the case. However, if you’re a screen reader user, you get a nice tabular representation of the data, so you also get the full picture. 😉
Let’s start with a description of the graph. It is a bar chart with seven blocks. Each block represents a day in the past week, starting with seven days ago and leading up until today. In each block, the parts each of the tracking protections Firefox applies contributes to a 100% whole. So it is immediately obvious how many of these trackers were social, cross-site tracking cookies, fingerprinters, cryptominers or tracking content. Not every day contains every piece of information. If a mouse user hovers over these, they get a tool tip of each item explaining what they are. Moreover, there are radio buttons for each type that color-highlight the particular type for each day.
The days are arranged horizontally from left to right, starting with seven days ago, leading up until today. The bars go up vertically. The code behind it is actually not that complicated, as it turns out. It doesn’t even use SVGs, it merely uses div elements that are filled with a CSS-generated coloring to represent the bars.
I now had two choices to make this accessible. I could either go by tracker type and then use each day’s values, or I could go by each day and then evaluate each block for that day. This was the closest resemblance to what sighted people are getting, so I settled on the latter approach. One thing was clear from the start: This had to be tabular data somehow. I then went in and applied parts of the WAI-ARIA table design pattern to these graphs. Mentally, I had to actually turn the graph 90 degrees sideways since tables are always top to bottom, and depending on your language, left-to-right or right-to-left.
In my mental model, the days then became rows, and the individual elements within each row became the individual cells within that row. The one common thing they have is that in column 1, the row header, is the day of the week, and in column 2 is the total number of trackers for that day. Column 3 through a max of 7 then become the individual trackers present for that day. This is a non-uniform table, since not every tracker is necessarily present on any given day. I decided to make this table as concise as possible, so each row is actually only the length of the block itself, and not the full width of seven columns. This is also what sighted users get, the blocks are different sizes depending on how many trackers there are.
Within each cell, the numbers already used for CSS and calculation of the percentage are put into an aria-label so the string reads well with screen readers, and it also conveys which tracker type is being shown. It is good practice to give everything that has an aria-label a semantic role. Because this information is graphical, I decided to give that information a role of “img”. This was the first time in the over 11 years I am dealing with WAI-ARIA, that I actually had a good use case for that role. As my testing revealed, while NVDA dealt with a simple div that had an aria-label on it just fine within each cell, JAWS was not so forgiving and ignored the text. Putting a role of “img” on it made JAWS recognize this as a graphic and it reads the table nicely now as well.
Putting things in order
After I had finished applying the table semantics, I found that the DOM order was not at all what the table semantics called for. aria-owns to the rescue! aria-owns is one of those attributes that you have to use very carefully, since it can mess with a lot of things. But when used the right way, it gives you enormous positive power over the accessibility tree. aria-owns takes a set of ID references, and reorders the accessible tree. That is the information assistive technologies such as screen readers use to convey the website meaning to their users. It turned out that the days of the week were not within the same container as the rest of the data, and they were actually in the opposite order as the graph blocks themselves. So, I had to collect the days not only one after another, but also shuffle them around and put each in its place in the table row so the screen readers would associate each day correctly with the rest of the data.
But before you try this at home, let me repeat the warning that aria-owns is a quite volatile attribute. If used the wrong way, it can seriously degrade the accessibility of your web site or application. If used the right way, and when it is appropriate, it can greatly enhance it. But always check your work, use the auditing features of the accessibility inspector, a screen reader, or both, and never forget the first rule of WAI-ARIA: Don’t use it unless you absolutely have to.
Check it out
If you are using Firefox to read this post, you can check out your own report by pressing CTRL+T (CMD+T if on Mac) to open a new tab, and typing about:protections in the address field. If you are curious about the code, you can check out my patch on Mozilla-Central, or view the whole source and test file. These all open in separate tabs, too.