Tags:
Screen readers are an important part of how people browse the web, especially so for those people who can't see a screen. However, screen readers can struggle presenting your visuals correctly if you haven't written clean code and created well thought out content that can be understood and presented as you intended. By understanding and considering the types of content and the problems that can occur, you can be in a better place to prevent those issues before they even happen, and this guide can help. With the upcoming European Accessibility Act there is going to be an even greater need to ensure that websites work well with screen readers.
Contents
Using the Right Characters
Screen readers will read out the content you give it, but sometimes what you give it isn't what you think you're giving it. There are a few different things to consider.
Avoid Using Special Font Letters
This isn't a warning about your usage of fonts, but of special characters (actual special characters, not the punctuation that password checkers refer to) that you might use to make your text stand out. What I'm talking about is the sort of text you see sometimes cropping up on social media.
The reason it creates problems, is that those aren't actually letters (even though they look like them), but are actually cosidered to be letter-like characters, and some are valid letters in other alphabets that slightly resemble a letter in the Latin alphabet.
I tested the output of one of the many Unicode Text Converter websites against a couple of screen readers. For the most part, a screen reader will completely ignore most of the symbols, meaning that your content is effectively invisible to people relying on a screen reader. In-fact, of all those styles tested, only the fullwidth text and acute diacritic options tested correctly for me. Some fared less well, and in particular the CJK+Thai, inverted, and reversed options were interpreted as mostly junk, and my screen reader would speak out mostly just single letters.
For your own website, there's no real need to use these symbols for decorative purposes, as there are better ways to style text using any font you wish. I'd recommend against using this technique for social media though, as you are creating content that people can't hear.
Using Correct Symbols
Many years ago I worked on a website that had taglines for products demonstrating how much better they were than other competing ones, specifically with text that they intended to be read out as "3 times longer lasting". However, the text sent through was for a heading, and the request was for all uppercase text, and instead of the word "times".
Given it was a heading, the text used was "3X LONGER LASTING". When I tested this out with a screen reader, it read that heading out as "3 ecks longer lasting", obviously not ideal. The quick fix solution would be to use the correct symbol instead, the "×" symbol, which would be read out as intended.
There is a minor problem with this solution though, visually the appearance of the text will change. Most of the time, this is fine, but if it's not, you can work around it with code like this:
3<span aria-label="×">X</span> LONGER LASTING"
Visually, it will appear as intended, but the aria-label
will override the letter and put the correct symbol in its place to be read out.
You should consider these two approaches when using letters in place of more suitable symbols, and there are plenty of other common situations that you might run in to as well:
- ™ symbol instead of using superscript letters TM.
- ½, ¼, and ⅓ (among others) for fractions instead of a mix of subscript and superscript numbers like 1/2.
Avoid Invisible Characters
A recent Reddit thread I saw mentioned the problem of trying to make text fit perfectly according to a design. This is a problem I've run into many times in the past. Most often it comes up when trying to make translated text fit into an already established design, especially with German words.
The Reddit thread mentioned using a soft hypen in the middle of long words to force break them. The soft hyphen is an invisible character that helps indicate to a browser where it should insert a line break in a word if it would otherwise be too big for its container.
The problem with this approach is that it breaks with screen readers, which interpret that as a hard break rather than a soft one, and can lead to some words being read out completely incorrectly. Consider the word "hyperbole", which should normally be pronounced as "high per bolly". Now, imagine the scenario where a soft hyphen is inserted between the letter "r" and "b". A screen reader would now pronounce that as 2 separate words: "hyper bowl". Anyone listening to their reader saying that would be very confused by what the intended word was.
If you do find yourself trying to get content to fit a design, consider the alternatives:
- Is there an alternative to the content that could be used instead? There are often many viable alternatives, even with translated content.
- Can the design be amended to account for the larger content? This could be making the content area larger, or the font smaller.
- Use the soft hyphen but wrap the word in markup like this to allow screen readers to read it out correctly:
<span aria-label="hyperbole">Hyper-bole</span>
Accessible Emoji
I've written before about how to make emoji more accessible, but I'll recap the specifics regarding making them work better with screen readers (although emoji accessibility is not limited to just these issues). The main issues that will affect screen readers are:
- Using emoji for the visual appearance without consideration of the underlying name of the emoji.
- Some emoji are not read out at all by all screen readers.
Emoji for Visuals Only
From one type of character to another; emoji are most typically used in text messages and short messages like Tweets (still not sure what these should be called now!), it's also quite typical for some emoji to be used for what they appear to look like, rather than what they were originally intended to mean. The example I highlighted in the article I wrote back in 2019 used different crying face emoji:
"You won't believe what happened at work today 😂"
"You won't believe what happened at work today 😭"
While they might visually appear almost identical, the two emoji express different emotions, one positive (face with tears of joy) and the other negative (loudly crying face), which would completely alter the meaning of the sentence when read out by a screen reader.
The best way to resolve this is to pick the correct emoji, based on the actual meaning. However, if you prefer to use a specific emoji, despite its meaning, you are really treating the emoji as an image, so you can mark it up as one in your code:
Fancy <span role="img" aria-label="fish and chips">🐠🍟</span> for dinner tonight?
Here, the emoji would be read out as "fish and chips", rather than "tropical fish french fries", a very different type of dinner indeed, which would happen if just using the emoji on their own.
Supporting Unsupported Emoji
While the state of play is a lot better now than it was 6 years ago, there will still be situations where emoji aren't read out correctly by a screen reader across every device and operating system. In order to present them correctly, use the typical approach of wrapping it up in a <span>
and giving it an accessible label to help present it properly.
Graphical Elements
Leading on from emoji are other types of graphical elements. The web is full of graphics, whether its logos, icons, photos, videos, charts, or some other media, and these aren't always given the right approach to make them available to assistive technology.
Alt Text as a Replacement
Too often I see alt
text being used to describe an image, and this is also the approach taken by a lot of the AI overlays that aim to "automatically fix accessibility issues" on websites. Even putting aside the fact that AI can get descriptions wrong, the approach of simply describing an image is not always the best.
An image is not just about the image, it's about what it represents. Why was the image used, and what does it mean to have it placed right there in the content? Meme images are probably quite a good example of this. Consider this text and the accompanying image:
Here, I've given the alt
text for the image as "stubborn goat meme image", mirroring the implied meaning behind the sentence (as everyone knows that Lego is most definitely for everyone!) But what if I had just described the image instead using text like "white goat with head up"? That would be completely technically correct, but also completely wrong as a text replacement for the image given the intention I had for using that specific image.
A good way to check if you're using the right alternative text for an image is to disable images in a website entirely, so that you end up seeing only their replacement text instead. Does that text make sense in the context of its surroundings? If not, it's a strong indication that it's not replacing the image.
It's also worth considering that the alt
text for an image is not only used by screen readers. It's also shown by the browser before the image loads. So, if the user is on a slow connection, or the image is missing, the text is shown until the browser can load it.
Presenting Information Correctly
Sometimes a graphic is used on a web page to convey specific information. This could be as simple as a name in a logo, or as complex as a bar graph depicting the results of a survey.
Simple Replacements
Simple logos can use the standard approach:
<img src="ACME Co." src="acme-logo.jpg"/>
If you're tempted to add in the word "logo" or "image", don't, unless it absolutely is necessary to understanding the image. Going to the earlier point about image alt
text being used as a valid replacement rather than a description of an image, consider whether or not you need those extra words or not.
Complex Information
Charts and graphs often contain a lot of information. In-fact, their purpose is to turn a lot of information into something that's more easily digestible that can be easily understood at a glance. So, how do you flip that over to present the information in a way that can be read out?
Depending on the complexity of the graph, you could represent the data either as alt
text or using the <figcaption>
approach. I wrote about both approaches to chart text replacements some years ago.
<figure>
<img src="favourite-colours.png"
alt="Pie chart showing preference for primary colours"/>
<figcaption>
<table>
<caption>Favourite primary colours of 45 people asked in public</caption>
<tr>
<th>Colour</th><th>Number of Responsdants</th>
</tr>
<tr>
<td>Red></td><td>20</td>
</tr>
<tr>
<td>Green</td><td>15</td>
</tr>
<tr>
<td>Blue</td><td>10</td>
</tr>
</table>
</figcaption>
</figure>
SVG for Very Complex Graphics
Sometimes, even using <figcaption>
is not enough to best represent an alternative to a more complex image. SVG is great for this though, because it's a markup language that allows you to use the very familiar accessibility attributes that you use on other HTML elements. The most important I've found for this are:
aria-hidden
to hide the purely presentational parts of the SVG.role
to give the other parts of the SVG some more relevant semantic meaning.aria-label
to add further text labelling to elements.
An example I've used in the past is a line graph showing popularity of device usage across the hours of the day. The graph markup would look something like this for each point on the graph:
<g role="list" aria-label="Visitors on mobile devices...">
...
<path role="listitem" aria-label="3 visitors at 3am" d="..."/>
<path role="listitem" aria-label="2 visitors at 4am" d="..."/>
<path role="listitem" aria-label="2 visitors at 5am" d="..."/>
<path role="listitem" aria-label="1 visitor at 6am" d="..."/>
...
</g>
Within the accessibility tree, you'll see SVG is now presented as if it were a standard list, making it much more available to screen readers presenting the SVG to the end user.
While this may be quite some additional effort to achieve, it does ensure that all users are given the same opportunity browsing the content of your website.
Interactive Elements
Following on from SVG, interactive elements are one whole area which can very easily trip up any developer with regards to their accessibility. That interactive element could be something like a complex bar chart, an interactive navigation menu, or some other intricate UI component. The most important things to take into consideration are identifying the element and its functionality, and handling its state and how it is represented.
Identifying Interactive Elements
The best way to identify interactive elements is to use elements that have the specific behaviour and role you need, but if nothing exists, fake it until you make it with the role
attribute and other aria-*
properties. There is a great list of widget roles on MDN for you to use to achieve this.
One of the example roles shown on the MDN documentation site is a tab interface that uses a mixture of tablist
, tab
, and tabpanel
roles to define different elements of the tab interface. A screen reader user will have the interface presented to them in a way that makes the most sense, allowing them to interact with it as intended. Further, the accessibility tree mirrors the visual behaviour, and contains only the active tab panel, ensuring that the screen reader isn't accidentally reading out the content of hidden panels when it shouldn't be doing so.
Handling State
The other part of ensuring interactive elements work well with screen readers is to correctly handle the state of elements, particularly those elements that change over time.
A basic example is a menu that has closed and open states, such as the humble "hamburger" menu used on many sites across the web, which uses the aria-expanded
attribute to indicate whether it's open or closed. Setting this property to true
, a screen reader can indicate to the user that it's open and usable.
Again, MDN to the rescue as it has a very comprehensive list of states that Javascript can interact with to present elements and their changes over time to a screen reader.
Aiding Faster Navigation
When a sighted person browses the web their eyes will dart all over the page, very quickly scanning information, and taking in all the parts of the page that are given visual importance. However, if you can't see, and you're relying on your ears to navigate, then you will be slowed down somewhat as you wait for things to be read out.
One way that screen reader users compensate for this is by having different ways to navigate around the page, and this includes methods to quickly jump to key areas of the page.
Landmark and Sectional Elements
There are a lot of landmarks that you can use (and that you probably already are):
<main>
<header>
(when used as a top-level element, not when it's inside something else, like a<section>
or<article>
)<footer>
(when used as a top-level element, not when it's inside something else, like a<section>
or<article>
)<nav>
<aside>
<section>
(but only when given an accessible name)<form>
(but only when given an accessible name)
Some of these only become landmarks if you give them accessible names. This is done by adding either an aria-label
or aria-labelledby
attribute to the HTML element.
Link Text
You have probably heard of this one before, but if not, it's always important to give your links clear text that help identify them. Don't use text that says "click here", because if someone is trying to use their screen reader to jump to a specific link, they need to know what that link is for. As a bonus, this will also greatly help with the general SEO of your site as well.
Heading Levels
Heading levels should follow a logical order, creating a structure for the content of your page. Don't skip levels (e.g. an <h3>
immediately following an <h1>
). The Web Accessibility Initiative has a great page about headings detailing how to best structure and use them.
Form Elements
Form elements are probably one of the most covered groups when it comes to articles on accessibility, but at the most basic level, you must ensure that every single form element has an accessible label. For most elements that would require you to use the <label>
element, which associates a visual label with the form element.
<label>Forename:
<input type="text" name="forename"/>
</label>
<label for="surname">
<input type="text" name="surname" id="surname">
</label>
Some elements, like buttons, don't need a <label>
, as they have their own inherent methods of providing a label:
<input type="button" value="Post comment"/>
<button>
<img src="button-image.jpg" alt="Post comment"/>
</button>
Testing With Screen Readers
Understanding and applying everything mentioned in this article is not enough, you need to actually test what you are developing, and the best way to test accessibility efforts for screen readers is to use a real screen reader.
The desktop space has a lot of viable options:
- Jaws - a paid for reader for Windows, and is currently the most popular (just slightly ahead of NVDA).
- NVDA - a free Windows-based screen reader, almost as popular as Jaws.
- Narrator - built into Windows, but not very much used.
- VoiceOver - this is the screen reader offered by Apple, and is available across their desktop, laptop, tablet, and phone products.
- Dolphin is another Windows reader, but quite expensive which might explain its low use.
- Orca - the most popular screen reader on Linux, and free.
If you don't fancy forking out for one of the paid options, I'd definitely recommend NVDA, and is the main one that I use for testing on Windows. Obviously, if you're on a Mac then the best option is to use VoiceOver. Learn how to navigate and use the shortcut keys provided by your chosen reader. It is a bit of a learning curve at the beginning, but it will get easier with time as you learn to use it.
Conclusion
There are a lot of things to bear in mind when you're developing to ensure that you're giving all of your users the best possible experience. Screen readers are a major part of the web for some people, and it's important for you to understand what they are, how they behave, and how to make your code work as well as it can with them.
Also, with the upcoming EAA law that will begin to be enforced this year across Europe, there is an even greater need to know how to make your websites more accessible.
Comments