written by
Aagje Reynders

Getting started with accessibility in Angular

Performance 2 min read

Last month, I was asked to make an existing project more accessible. We were looking into small changes to impact the accessibility significantly, as there was not a lot of time or budget available… But when is there, really? 😉

One of the first things that I wanted to fix was making the applications more keyboard-accessible. There were two main goals in this accessibility sprint:

  1. having a visible outline (read my other blog for more information)
  2. being able to tab to every clickable item

This blog will focus on the second goal: ensuring you can navigate through your page to all clickable items with only a keyboard.

keyboard accessibility
Next

Wait, but with the correct HTML, this should work, right?

Correct! Items like anchors and buttons have predefined roles that would allow you to navigate to them with only your keyboard. But that only applies when you correctly use HTML, which was not the case in this specific project.

Working component-driven can lead to incorrect use of HTML

We developed visual components in Angular, so clickable items could be everything: divs, icons, paragraphs, spans,... Everything that’s not a button or anchor. That’s a problem. How can we fix it?

Fix the HTML

You can fix the HTML. This should always be your first consideration, especially when starting a new project. However, it isn't always possible when you have a lot of existing code.

Use tabIndex

You can use an HTML attribute tabIndex, where you can give a tab order to your element. Not only does it give the item an order, but when adding the attribute, it will be included in the tab navigation. Great! However, it is very annoying to manually add this to, say, 50 components, am I right?

You can also use tabIndex to disable the tab by giving it a -1 value. This is an easy fix for browsers who interpret the HTML weirdly or when the item is not always clickable.

Make a directive (my solution)

Instead of manually changing all the components, risking creating bugs, or forgetting some pages, I made an Angular directive. You can probably do something similar in other frameworks as well.

The directive will look for all HTML items that contain a (click)="" attribute. Which would suggest the item is clickable. Moreover, it adds the correct role and tab index to the item. It’s a quick fix that can make your application more accessible.

import { Directive, HostBinding, HostListener } from '@angular/core'; 

@Directive({ selector: '*[click]:not([role]):not([tabindex]' })
export class ClickEqualsEnterDirective {
@HostBinding('attr.role') role = 'button';
@HostBinding('attr.tabindex') tabindex = '0';
@HostListener('keydown', ['$event']) onKeyDown(e: any) {
if (e.which === 13 || e.which === 32) {
e.preventDefault(); e.target.click();
}
}
}

TL;DR

Making your component library or more extensive web application accessible with the keyboard is not always easy. Making a directive that can look for items that use a (click) attribute was my way of making this a long-term solution without refactoring all the components.

Have you struggled with this issue? Let me know how you fixed it in your application!

Wheelhouse Immersive technology