The most common offender to a11y in Angular apps that I have seen is how click events are used. With Angular's template binding syntax, it's straightforward to create click events on practically anything we want.
<!-- Incorrect -->
<div (click)="save()" class="btn">
<!-- Correct -->
<button (click)="save()" class="btn">
To keep our application accessible we want to always use the
(click) events. This helps in a few different ways. First buttons are
easily focusable. Using just the keyboard, we can tab to a button element,
assisting users with any motor disabilities. Using a button as well by default
provides a focus style that outlines the button currently focused. This
functionality allows it easy to navigate and tab the active button.
Links / Anchor Tags
Links (anchor tags) in Angular follow similar rules to buttons when it comes to a11y. With links, we want to ensure we don't remove focus styles. This allows navigation easy to use with keyboards.
Links should not be used for button click events. If you need a button to look like a link, then style it with CSS. Links should primarily be used for linking between navigation views.
<!-- Incorrect -->
<div (click)="navigateToAbout()" class="btn">
<!-- Correct -->
<a routerLink="about" class="btn">
Using links for navigation provides a few benefits. Links allows context to SEO search engines and a11y tools. With links, this makes it clear that the interaction will cause navigation to elsewhere in our app. Using links for navigation allows our app to be easily shared and bookmarkable.
In Angular, the form system is quite robust and feature-rich, but there are some best a11y practices to keep in mind when constructing our forms. Most Angular forms follow the same rules for any accessible HTML form.
First recommendation is use HTML
form tag. Using a form tag makes it clear to
the user that this is an input form to gather data. This also makes it easier
for keyboard tabbing and navigation. When an HTML form is created, it allows
saving the form to be triggered by not just a submit button but also using the
enter key by default. Using Angular's Reactive Forms
this is fairly easy to do.
<form [formGroup]="searchForm" (ngSubmit)="search()">
When creating inputs always have an associated label to describe what the input
is for. You can do this with the
label element tag. If you don't want a
separate label, you can use the
aria-label in combination with
Inputs also have focus styles just like buttons and link. Make sure to leave the
defaults on or if its a custom input make sure to add focus styles back to the
With some instances in Angular we may want to make a custom component but also want to ensure it is accessible as well. We can add particular ARIA (Assistive Rich Internet Applications) attributes to mark our templates in a way that explicitly describes what our component is doing making it more accessible.
In the Angular Pokedex app we have a custom menu nav component that opens and
closes as a slide out overlay. In our app, we want to use ARIA attributes to
describe when the menu is visible explicitly. ARIA attributes help screen
readers understand when dynamic content has entered into view. There are many
ARIA attributes with different forms of functionality but for our example
we will be using
<nav class="nav" (click)="navOpen = !navOpen" [attr.aria-hidden]="!navOpen">
<a routerLink="/pokemon" class="nav__link" [attr.tabindex]="navOpen ? 0 : -1">
<a routerLink="/about" class="nav__link" [attr.tabindex]="navOpen ? 0 : -1">
With Angular's property binding syntax, we can easily bind to the attributes of
our navigation allowing us to set the aria-hidden property with
[attr.aria-hidden]="!navOpen". Now when we toggle our nav, the Aria attribute
is explicitly set to describe when the navigation is visible or not on the view.
Find out more about ARIA here.
There are still many more topics on accessibility such as color contrast and a11y test tools. This just scratched the surface of where Angular and Accessibility meet. To find more resources on a11y check out the fantastic A11Y Project.