Common accessibility problems to avoid
Happy new year, everyone! At Mutual, we've been thinking about what our goals are for 2020. After hearing a talk on Accessibility last year at Gatsby Days 2019, I've decided that I want to spend this year improving my knowledge of web accessibility.
I've been putting a lot more thought into it on my recent projects, so I wanted to highlight my findings so far, such as the common problems I've been running into and what I've been doing to avoid them.
What tools and process of testing do I use?
The first tool I use to test a page is Google's auditing tool, Lighthouse. Most developers will probably already be familiar with this, especially when used to test the performance of a website. However, Lighthouse does come with a handy accessibility test. Whilst it isn't very in-depth, it does help catch common issues.
Microsoft's Accessibility Insights extension is another really useful tool that every developer should have installed.
Usually, after running a Lighthouse audit to catch any immediate issues, this is my next port of call. Like Lighthouse, it offers a Fast Pass feature, which will scan your page and flag any common accessibility problems. After running that for good measure, the majority of time is spent on their Assessment page. This is broken up into categories (Keyboard, Focus, Landmarks etc), each with a checklist. Ideally, you should go through each category's checklist (that is relevant to your website), read the detailed items and check whether your page fits the bill.
By the end, whilst it can be time-consuming, you can trust that you have given your website a very thorough inspection.
Don't rely on automated checks
As mentioned above, automated tests made up a good chunk of my testing. But, I quickly realised that they shouldn't be trusted.
By implementing some common accessibility practices and running a Lighthouse Audit, I found it wasn't long before I was scoring 100 on my pages. It would have been easy to have stopped there and called it a day.
However, when I started manually going through the Accessibility Insights checklist, I would spot some obvious mistakes that didn't get picked up. For example, there were some images in a slider that each opened a lightbox. But, they were not wrapped in button or anchor tags, so they weren't navigable by keyboard.
Whilst it was a simple fix, I noticed that my Lighthouse score had now dropped and it was spitting out errors. It turns out my slider library added aria-hidden="true"
to any unfocused slides, and you're not allowed to have that attribute on any tabbable elements.
This raised a deeper accessibility issue that I had to solve. One that I would not have spotted had I simply relied on the Lighthouse audit.
Nothing beats first-hand experience
As I tried to show above, a perfect score on an audit doesn't necessarily mean your code is perfect.
I found the most bulletproof method was to try navigating the website myself, using only a keyboard and/or screen reader, and asking the question: “does this feel right?”
Here are some more specific things I also kept in mind:
- Is the page fully functional and navigable without a mouse?
- Is it obvious what element is focused?
- Is your focus location where you expect after opening or closing a modal or dropdown?
- Does keyboard navigation progress in a sensical and linear manner?
This method really opened my eyes to issues that were not getting picked up by automated tools.
Never remove focus styles
I'll throw my hands up and admit that :focus { outline: none; }
is something I have written before in the past. Whilst it can be a common request from clients or designers to remove the focus outline from elements, it is something that should never be done.
Outlines are essential. Without them, navigating through a website with a keyboard is impossible, as it removes all visible indication of a focused element.
If you're not happy with the browser's default, then consider changing the style of the outline. (Just make sure that it is still visually obvious.)
Otherwise, if you must remove the outline, then consider changing the style of the element itself when focused. However, don't rely on colour alone as a visual indication of focus, as this may prove unhelpful for colour-blind users.
Don't forget to trap focus
Trapping focus is another common issue that I've often forgotten about, but it is really important for keyboard-only navigation. When a dialog box (modal, lightbox, nav dropdown etc) is opened, the user should only be able to tab between focusable elements within it. If their focus is not trapped, then they will be able to tab through to the elements on the page behind, causing their position to become confused and lost.
Whilst there are a few tutorials out there for building your own custom JavaScript solution, I really like David Clark's Focus Trap library. It's really easy to get set up, and it has a range of options and functionality.
Don't forget to make sure the first item in your dialog box gets focused when you open it. Closing it should also return focus to the element that opened it.
Make sure the context is always clear
We should always make sure content inside a focusable element is clear to screen readers out of context. If it is vague then it will be difficult for users to know the purpose of the element.
Let's look at an example:
<!-- Bad --><p><!-- This will be read as “Link. Click here.” -->To find out more about us, <a href="/about-us">click here</a>.</p>
This can either be solved by rewording the sentence or by using the aria-label
property:
<!-- Better --><p><!-- This will be read as “Link. Click here. About us.” -->To find out more about us, <a href="/about-us" aria-label="About us">click here</a>.</p><!-- Ideal --><p><!-- This will be read as “Link. About us.” -->Find out more <a href="/about-us">about us</a>.</p>
Assist screen readers
One thing we can do to assist screen readers is to make use of the WAI-ARIA semantics.
As touched on above, a screen reader will read an aria-label
when the element is focused, so it's particularly useful on elements whose context is not clear:
<!-- Example 1 --><div id="Modal"><p>Thank you for opening this modal.</p><button aria-label="Close">X</button></div><!-- Example 2 --><button aria-label="Open lightbox with image"><!-- NOTE: It is not necessary to write “An image of John Smith”, as a screen reader will indicate that the element is an image before reading the label. --><img src="/img/john-smith-headshot.jpg" alt="John Smith" /></button>
If you already have a clear heading that could be used as a label, then you can use the aria-labelledby
attribute instead:
<nav aria-labelledby="useful-heading"><h2 id="useful-heading">Useful links</h2><ul><li><a href="/privacy-policy">Privacy Policy</a></li><li><a href="/terms">Terms & Conditions</a></li></ul></nav>
You can also define your markup using ARIA's role
attribute.
Combining it with aria-label
or aria-labelledby
is helpful for organising areas of markup for screen readers, especially if there are multiple instances of the same role:
<section role="region" aria-labelledby="about-heading"><h2 id="about-heading">About us</h2><p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Vero officia doloremque saepe eos et hic provident sit dolorum ullam, qui animi. Ad rem inventore itaque beatae autem? Nulla, est nihil.</p></section><section role="region" aria-labelledby="team-heading"><h2 id="team-heading">Meet the team</h2><p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Vero officia doloremque saepe eos et hic provident sit dolorum ullam, qui animi. Ad rem inventore itaque beatae autem? Nulla, est nihil.</p></section>
Finally, adding these together can make for a very clear and accessible component:
<footer><nav aria-labelledby="info-heading"><h3 id="info-heading">More information</h3><ul><li><a href="/about-us">About us</a></li></ul><nav><nav aria-labelledby="social-heading"><h3 id="social-heading">Follow us on social media</h3><ul><li><a href="https://twitter.com/john-smith" aria-label="Twitter"><img src="/img/twitter.png" alt="Twitter logo" /></a></li><li><a href="https://facebook.com/john-smith" aria-label="Facebook"><img src="/img/facebook.png" alt="Facebook logo" /></a></li></ul><nav><section aria-labelledby="about-heading"><h3 id="about-heading">About us</h3><p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi, odit accusantium. Exercitationem necessitatibus illo facilis culpa id.</p></section></footer>
Wrapping up
It's become clear that running audits is not a fair assessment of the accessibility of a website. Whilst they help catch common markup or semantic issues, they are not a substitute for first-hand experience.
How accessible a website is and the way a user interacts with it is complex and nuanced. By keeping the techniques and ideas discussed in this post in mind, and by testing a website first-hand in a simulated way, we have a solid foundation for making sure our websites are accessible.