What I learned about svg accessibility (among other things) from NBC News' Senate What If project

By Joe Murphy

First published

NBC News published an interactive that lets readers game out what might happen to the U.S. Senate's balance of power in the 2022 midterm elections. From the start making it work on screen readers and other assistive devices was a goal, here's some of what we did and what we learned.

Our team had plenty of help getting this to work — from the company's in-house accessibility expert, to the excellent TPGi consultant we worked with, to the user testing we were able to do with people who use assistive devices — these people helped us understand what worked and what needed improvement in the interactive we built.

The little things we learned about making graphics and interfaces accessible

Everyone on the team each took parts of the accessibility tasks. Here's some of what we learned in the process:

How we made the SVG at the core of the interactive accessible

At the core of the interactive, NBC News’ Senate What If, is an SVG graphic that acts as interface, allowing readers to toggle through the states with open Senate races.

JoElla C. led development on that SVG component, which was managed with d3. To make it usable on a screen reader she took these steps, under the advice of the TPGi consultant Aaron F:

  1. An application role. On the parent svg element, add role="application" to tell the screen reader to not intercept keystrokes meant for the SVG, aria-label="Create your own Senate forecast. Select winners for the 10 closest races, or toggle show all to select from all 35 races. Select an item once to toggle to Democrat, select one more time to toggle to Republican." to describe what the element does.
  2. Bits within the U.S. state elements:
    • Add role="button" to the individual U.S. state svg elements.
    • Add data-selected="true" to the svg element when it was selected.
    • Add tabindex="0" to the svg element when it was selected, and tabindex="-1" to all the other element tabindexes when they were unselected. This lets a user, should they tab away from the interface and then tab back, return to the element they were on before.
  3. A dynamic aria-label for each element. Maintain an accurate and up to date aria-label for each element. Here's an example of one: aria-label="Arizona. Selected as Republican win. Cook Ratings Forecast: Toss up."
  4. A dynamic aria-live region. In addition to the aria-label with the status of the element, we read aloud the overall status with an aria-live region. This took a div with dynamically added text when a new selection was made. The div had these attributes: role='status' class='visuallyhidden' aria-live='assertive' aria-atomic='true' aria-relevant. Here's an example of text that would be read aloud in it: Georgia selected as a Democratic win. Updated Senate seat count: Democrats 48, Republicans 45.
  5. Keyboard nav. We also implemented a keyboard navigation which is available once an U.S. state element is selected in the interface. Here's a little bit of the code that was used:

onKeydown(event, d)
          var tgt = event.currentTarget, flag=false;
          switch (event.key) {
          case 'Left':
          case 'ArrowLeft':
            this.moveFocusToPreviousState(tgt);
            flag = true;
            break;

          case 'Right':
          case 'ArrowRight':
            this.moveFocusToNextState(tgt);
            flag = true;
            break;

Note: This interactive will change its shape on election night and afterward, the words here described it as it was in October 2022.


You can email me at joe.murphy@gmail.com.