DEV Community

Sarah
Sarah

Posted on • Originally published at fossheim.io

Dataviz accessibility review: what we can learn from the Norwegian 2023 election graphs

This was first posted on my blog: fossheim.io.

--

During the 2020 presidential election night in the United States, I reviewed the data visualizations used by the major US news networks, and used it to illustrate some dataviz accessibility dos and don’ts.

Now that Norway had its local elections (we were voting for a new regional and city government), it's time for a repeat of the concept and take a closer look at the dataviz accessibility of the graphs used in the Norwegian media.

Earlier this week the Norwegian news NRK reported that none of the Norwegian municipalities were conforming to web accessibility requirements, so I was definitely curious how the different charts would perform.

Scope

During the election night, I inspected the following websites:

  • valgresultat.no, the official results page by Valgdirektoratet (the electoral directorate)
  • NRK.no's dashboard, created by the state-owned public broadcast
  • VG's dashboard, a popular privately-owned newspaper
  • Aftenposten's dashboard, another popular private newspaper
  • Note: I don't currently work with/have a relationship to these companies, I picked their dashboards because they're popular websites and the first ones that up when I looked for the election results.

And paid attention to:

  • Screen reader (VoiceOver) behavior
  • Focus order and keyboard interaction
  • Visual elements such as color contrast
  • Semantics, labels, names, and ARIA best practices
  • Understandability of the data and interactions
  • Chart controls

For client work I would test and review these areas in-depth, each with their own set of criteria, relate them back to WCAG where relevant, and also assess how the page frame and other elements on the page influence the chart accessibility.

For this article, however, I mainly focused on finding examples that:

  • Illustrate some of the important dataviz accessibility best practices, or
  • Highlight common or interesting accessibility mistakes, or
  • Explain certain accessibility concepts

And to not overcomplicate the article, the websites were only tested in Safari and with VoiceOver.

Now, let's dive into some of the findings 👇🏻

Data visualizations require accessibility work

When it comes to web accessibility, writing semantic HTML will get you a long way already.

For example, if you develop a website and do things like picking <button>s for buttons, adding alt text to your images, structuring your content with heading elements (eg: <h1>, <h2>), then you have already started the work of making your website more accessible.

It won't necessarily be WCAG compliant or lead to a good and equal experience for disabled people. Typically more accessibility work is needed for that (and not just from the development side), but it does create a solid base. For example:

  • <button>s can by default be activated by clicking them, pressing enter (key down), or releasing space (key up).
  • alt="..." text on an <img> elementgives blind people and those with low vision (and others using assistive tech like screen readers) a description of the image and access to the same info.
  • <table>s come with their own screen reader navigation: when testing with voice over, I can use cmd + shift + up/down/left/right to move the screen reader focus/cursor between the cells in both dimensions.

With dataviz accessibility, however, the situation is a bit different.

Most visualizations are built using <svg>s. With SVG, we use elements like rectangles, circles, or paths (<rect>, <circle>, <path>) to build our visualizations. Those elements carry no semantic meaning to assistive technologies, and come with no out-of-the-box keyboard interaction. The same is true when building visualizations from <div>s and <span>s.

Data visualizations typically are inaccessible by default. If we don't actively curate accessibility of our charts, we will end up with visualizations that are varying levels of inaccessible.

Graphical elements that carry meaning need text alternatives

Let's take a look at this chart from Aftenposten:

Video in the original post

Video description: Bar chart showing the shift in votes for each party compared to last elections. The category labels (logos of the parties) are displayed vertically. If a party has a negative shift, the bar is displayed on the left side, positive shifts to the right side. I'm using VoiceOver on the page, and the only items on the chart that are reachable by screen reader are the values next to the bars, but not the party names.

The only thing read out are the text elements (<text>) which contain the numbers.

The logos are added as an SVG element consisting only of <path>s, which by default do not contain any info for screen readers to parse. As a result, only the result numbers are announced, not the parties they correspond to.

This makes the entire chart inaccessible to screen reader users. It's just a sequence of unlabelled numbers.

We may need to provide additional context and structure to the data to make it screen reader accessible

Let's take this example is from VG.

Here the screen reader announces all the images and text elements (in itself this is fine), but there is no extra info about what the numbers represent, how they relate to the images, or how the parties are structured.

Video in the original post

Video description: Comparison/progress chart showing how close the red coalition and blue coalition are to the 30 mandate majority. A screen reader is used to navigate between the different text elements of the chart, which are announced in the following order: left candidate picture alt text, the candidate name, party, amount of mandates on the left, the label "30 mandates", amount of mandates on the right, a list of text labels that just contain party abbreviations ("R", "MDG", "V") from left to right, right candidate picture alt text, the candidate name and party.

Visually, we have:

  • The left / red parties, on the left side of the graph
  • The right / blue parties, on the right side of the graph
  • Name, party, and picture of the main person on either side
  • Total amount of mandates for either side, written next to the name
  • How close either side is to the 30 mandate majority
  • Underneath each side (red/blue), which parties belong to them
  • The amount of mandates for each of the parties

Comparison/progress chart showing how close the red coalition and blue coalition are to the 30 mandate majority, through a bar that's filled with red on the left, gray in the middle, and blue on the right.   There's a "30 mandates" text label in the middle. On either side of the bar there's the name and picture of their main candidate, the name of the main party, and the amount of mandates the coalition has. Underneath each coalition the parties that belong to it are listed, along with the amount/proportion of mandates that belong to them (1 square in their party color per mandate, grouped in colored areas with a text label on top). Underneath the chart are tickboxes for each party. On top of the chart there's a main title and a description explain the chart, a location title, and percentage of votes counted.

The screen reader announced, in this order:

  1. Image description of the candidate on the left
  2. First name, last name, party of the candidate on the left
  3. Mandates of the left (without label, eg. just "27")
  4. "30 mandates"
  5. Mandates on the right (again without label)
  6. Initials of all the parties, from left to right
  7. The full name, party, image description of candidate on the right

Without any of this data being structurally grouped, and without any additional labelling, this doesn't tell us the same as the visuals.

We're not told any info about the size of the parties or which side they belong to, and the number of mandates for the right side is not announced along side its label (the candidate name and picture).

Some of the following could be done to improve this:

  • Grouping and/or connecting the candidate name, party and amount of mandates. This includes tidying up the order of the elements. Eg: "Raymond Johansen, AP: 28", "Eirik Lae Solberg, H: 30"
  • Grouping the parties by left/right side, and labelling each side. Eg: "Red block" (unordered list) and "R" (list item), "SV" (list item), etc.
  • Adding the amount of mandates to each of the parties. _Eg: "R: 4 mandates", "SV: 6 mandates" _

The chart is interactive, and parties can be toggled on/off to see how many mandates each side would have, and how that changes who has the majority of mandates. Those updates are communicated visually, but screen reader users also need to know:

  • Which of those parties are toggled on/off when going through the visualization of the parties and their amount of mandates
  • What the tick boxes are meant for (a label to explain their purpose), and also that the visualization updated after (un)ticking a box

Similar charts can have different valid solutions

NRK's results have a similar percentage-based visualization as VG. NRK's isn't interactive, however, and so they can take a different approach to it: turning the visualization into an image with alt text.

The alt text says the % of votes for the red parties, % of votes for the independent parties, and % of votes for the blue parties. This is the same as what's represented visually.

Video in the original post

Video description: I'm using the screen reader to navigate between the elements on the page. There is a list of visualizations showing the percentage of votes the red block (on the left) has compared to the blue block (on the right). The charts are announced as images with alt text, like for example: "Red block: 45.8%, Independent parties: 1.7%, Blue block: 52.5%. Red block. Blue block.". They're wrapped in links, along with the name of the city and the % of votes counted.

Even though there's a small bug with it (the actual "red parties" and "blue parties" are not announced, but their subtitles are), alt text like this can be sufficient for this type of chart in the way NRK used it.

The Aftenposten example from earlier used the same chart type and same data as NRK, but has interaction attached to it (tickboxes on the bottom that filter results within the chart), and also visualizes the party names according to the amount of mandates they have. This will also lead to different screen reader solutions, since turning the chart into an image with alt text would take some of that functionality away.

Not testing visually hidden labels can lead to incomprehensible data

A mistake I often come across in reviews is improper labelling elements.

Sometimes people do indeed add screen reader alternatives, but either use the wrong properties, or add information that's incorrect or not useful.

Often those type of issues happen because if you don't use assistive technology yourself, you won't notice the content and behavior of visually hidden labels until you inspect the code, test the page with a screen reader, or otherwise try to assess the accessibility.

One of the charts where I suspect this type of testing was lacking is this distribution graph by Aftenposten.

Video in the original post

Video description: The screen reader focus is moved down a list of cities. For each city, the percentage of mandates each party has is visualized, and grouped by coalition. All the cities are announced as links with the following label: "Trondheim, 100% opptalt, parti navn, parti navn, parti navn, parti navn, parti navn, parti navn, parti navn, parti navn, parti navn, parti navn, parti navn".

It shows the distribution of mandates (per party, grouped by left/right coalition) for all of the major towns in Norway, all the parties were aria-labelled by (I assume) their placeholder text: "Parti navn" aka "Party name".

As a result, VoiceOver announced results like: "Trondheim, 100% opptalt, parti navn, parti navn, parti navn, parti navn, parti navn, parti navn, parti navn, parti navn, parti navn, parti navn, parti navn".

One of the other things that's missing here as well is, again, the number of votes connected to each party.

How the mandates are distributed in the major cities. For each city, a horizontal list of colored bars (in the colors of the corresponding party) is shown, grouped by block/coalition (red/left or blue/right). The coalitions with the least votes have their colors dimmed. Next to each city it shows the % of votes counted, and there is a vertical line going through the middle of the chart, labelled "majority", to indicate which point either side has to cross to reach a majority.
Safari inspector showing the HTML structure of the chart. There's an unordered list containing an h6 and vertical separator (the majority label), and links with a href and title property set. Each link contains a list item, with several nested divs inside of it. One of the divs contains an em that has an aria-label (parti navn) set, and has the amount of mandates inside as text.

Some issues can always go past us for several reasons (everyone I know in tech is overworked and tired), but to me, bugs like these potentially highlight an issue with (or a lack off) accessibility processes, because:

  • Accessibility linters may or may not pick up on some of the issues connected to this
  • Code reviews (by team members that are accessibility-aware) increase the chance of these getting caught early
  • An accessibility focus in the content review process can discover issues with the alt text
  • Testing features with a screen reader would definitely flag these

So if those exist in production, it means that either the team isn't doing some/any of the above in their process, or they do a fair share of accessibility testing, but don't get the time to actually fix the issues that were raised.

Graphical elements require 3:1 contrast with the background

Most of the news media did actually fine when it came to the color contrast of the text. The main body text was black on a white background (or light text on a dark background in dark mode).

The text elements within the data visualizations generally had sufficient (4.5:1) contrast with their background as well, although there were a few hiccups.

For example, Aftenposten's green and red text showing the shift between now and the last election does not have enough contrast against white. But overall, the text color contrast requirement seemed well understood.

Bar chart with small green text that only has 2.59:1 contrast with the white background.

Things like bars on a bar chart, lines on a histogram, icons, and other graphical elements require a contrast ratio of at least 3:1 to make sure they're accessible to folks with low vision.

This was something most of the charts didn't accommodate for.

Aside from Valgresultat, all dashboards went for colors similar to the party's brand colors in their charts. That's good for cognitive accessibility, since people may recognize those already.

Some of those party colors are light, and for those NRK changed the font color for the overlaying text is changed to be at least 3:1 with the party color. That's good, and really improves the readability of those icons.

Dark green text against light green background: 8.42:1; Dark teal against light teal: 6.91:1

However, the same brand colors are used on the bars, which are graphical elements that require 3:1 contrast with the background. For example, SP's light green (#BBCB4D) has a color contrast of 1.79:1 against the white background, which is too low.

Light green bar against the white background has 1.79:1 contrast, light teal bar 2.18:1

Additionally, all the dimmed versions of the brand colors (that visualize the numbers from last election) lack color contrast agaisn the white background.

The other newspapers had similar contrast issues. The bright green and yellow that Aftenposten used had less than 3:1 contrast with the white background, and VG's blue was at 2.63:1 too low to be used for both the text and chart elements.

Blue text and bar chart that's 2.63:1 color contrast

The page itself needs to be accessible too

It's great if a visualization is accessible, but if it exists within a page filled with accessibility issues, then people may not even reach the chart at all.

Heading levels are important for explaining the structure and relationships of the content

Using subtitles/headings on a page introduces, structures, and sometimes summarizes the content. The text sets the expectation of what you're about to read, and the styling (font-size, weight, position, etc) of the headings says something about the relationship they have to each other.

Semantically, this structure and relationship is communicated by using heading elements with the correct heading level (<h1>, <h2>, <h3>, etc).

Valgresultat used an <h1> for all of their subtitles, not just the main page title. This took away the structure for screen reader users, and announces the page title on the same level as the subtitles in the footer, for example.

Headings menu in VoiceOver showing 7 heading elements, all level 1 (h1): valgresultat, lanfsoversikt, eksport av data for landsoversikt, adresse, postadresse, lenker, kontakt

In comparison, VG added headings to each of their sections, and the heading levels reflect the structure of the page. When browsing the headings menu in VoiceOver, I can tell that "Kampen om storbyene" ("The battle for the big cities") has information for 6 different places: Oslo, Bergen, Stavanger, Trondheim, Kristiansand, and Tromsø.

VG's page with VoiceOver headings menu open, showing a structure with one H1, and underneath a good structure with nested H2-4s.

Internationalization needs to be considered

Valgresultat has a language selector which lets the user switch between four different languages:

  • English
  • Norwegian (Bokmål)
  • Norwegian (Nynorsk)
  • Northern Sami (Sámegiella)

The text on the page updates to the selected language, but the language of the page never gets updated programmatically. According to the HTML lang code, the page is in English regardless of which language is selected.

Screen readers change their language and pronunciation based on the language of the content, and translation tools can base themselves on the lang attribute as well, so it's important that the language tag reflects the language on the page.

Maps are tricky to get right, often ignored

Across my client work I notice that maps are the chart type that spark the most conversation.

Do people want to navigate them sorted by name, continent, or value? What should the default sorting order be? Should keyboard users be able to navigate around spatially to neighboring countries? How do we visualize the data of small countries? Do we allow zoom? How does that work for keyboard users? How do we visualize borders? What are the color contrast requirements for adjacent regions?

All that to say: there's a lot to be considered when it comes to map accessibility. This is clear from how the different media made their maps accessible: they didn't.

The election maps were lacking screen reader interaction, table alternatives, and informative text alternatives

Across all the websites that used maps to visualize the election results, none provided a table alternative or direct screen reader interaction with the map.

Video in the original post

Video description: A bar chart and map. The screen reader announces the text labels on the bar chart, in chronological order (but reads the letters of the party names one by one), then the zoom buttons on the map are announced, and the map itself is skipped. There is no table alternative.

VoiceOver just skipped past VG's and Aftenposten's map. The zoom buttons were announced correctly, but the actual informative content was not there.

NRK's map was turned into an image with alt text, but the alt text only described what type of info was visualized on the map, not the actual data. NRK also made some extra effort to summarize the graph for everyone. Underneath the map they listed the parties and in how many municipalities they were in the majority.

Video in the original post

Video description: A map that's announced as a figure, and a text alternative is announced. However the text just describes the purpose of the graph (it's a map of Norway with the municipalities colored in the color of the party that had the most votes there). There is no table alternative. There is a list below the map, summarizing the amount of municipalities where each party is the largest.

This in a way provides a text format of the amount of color that's observable on the map, but there is no place to view a list or table with all of the municipalities and their biggest party.

Public vs. private sector?

Before this I was curious how the graphs of the public vs. private sector performed. While I did feel like more emphasis had been placed on accessibility and compliance on the two sources from the public sector, all the dashboards I inspected had room for improvement, including those from the public sector.

Currently the Norwegian public sector has to follow 47 WCAG success criteria, the private sector 35. All websites are tested had some issues against those. A couple of examples:

  • VG's map did not have a text alternative (SC 1.1.1)
  • NRK's bar charts were lacking color contrast (SC 1.4.11)
  • VG's party-colored text was lacking color contrast (SC 1.4.3)
  • Aftenposten's positive/negative numbers were lacking text contrast (SC 1.4.3)
  • NRK's map used only color to convey information (SC 1.4.1)
  • Valgresultat's language doesn't update (SC 3.1.1)

Both with the current and upcoming regulations in mind, the Norwegian news media and government definitely have some work left to do.

Looking for an accessibility review, training, or help with dataviz accessibility?

Are you after reading this article curious about how accessible your data visualizations are? Want to onboard your team on dataviz accessibility with a training session? Or have a chat about how to incorporate accessibility work into your organization?

🙋🏻 I'm an independent accessibility specialist with an offering focused on dataviz accessibility. If you're interested in hiring me for an accessibility project or are wondering how we can collaborate, feel free to reach out through accessibility@fossheim.io.

Top comments (0)