Let’s talk about building accessible Angular applications. Why? Because Angular apps are awesome, but the amazing things Angular lets you do are wasted unless you can build an app that everyone can use.

Accessibility (sometimes abbreviated as “a11y”) refers to designing software in such a way that it can be used by all users, regardless of any disabilities they may have.

While I’m not an accessibility expert, I can help you get started with accessibility in general and, more specifically, how to follow accessibility practices in Angular.

Accessibility 101

Before we get into auditing your applications for accessibility issues, let’s look at some common violations.

Modern HTML Tags

Modern browsers support a rich and diverse set of meaningful HTML tags, and yet the power of modern web technologies like Angular have made it easy for us to simply use div elements everywhere throughout our code.

This is bad.

Why? Because screen readers and other accessibility software see a div tag and they don’t understand whether this is a button, a paragraph, or a border rectangle.

Don’t do this.

Instead of <div class="btn">My Button</div>

Use: <button class="btn">My Button</button>

This applies to other HTML elements as well. When you can, use semantic HTML elements like nav, header, footer, section, article, and aside.

Use Aria Attributes

Sometimes you have to use HTML in interesting ways. For these times, you need to consider role tags as well as the Accessible Rich Internet Applications (ARIA) tag standards.

Commonly, you’ll need to pay attention to:

Note that If you need to bind the value of an aria attribute to something in Angular you can use syntax like: <div [attr.aria-expanded]="isExpanded">

There’s another aria tag to pay attention to: Regions that will receive live updates, inserts, or deletions should use aria-live. We’ll get back to this one later when we discuss announcing changes.

Since I’m not an accessibility expert and my focus here is more on enabling accessibility in Angular, I recommend you check out Ian Forrest’s excellent talk on web accessibility trends available on Pluralsight for free.

Integrating Accessibility into your Angular Workflow

Now that we’ve discussed general accessibility, let’s explore some more Angular specific scenarios.

Storybook Accessibility

I wrote previously about how I love using Storybook for quickly proofing Angular user interfaces. Storybook is an amazing library and has a number of very well done add-ons, including an accessibility add-on which can simplify accessibility audits.

You can install this add-on by opening your command line in your Angular application and then running:

npm i @storybook/addon-a11y --save-dev

This should install the necessary dependencies as a development-time dependency.

From there, you’ll need to register the addon in the .storybook/main.js file like so:

module.exports = {
  stories: ['../src/**/*.stories.ts'],
  addons: ['@storybook/addon-a11y'], // other addons hidden for clarity

Next, you need to add withA11y to each stories.ts file you want to be accessibility tested like so (noting lines 4 and 8 in particular):

Viewing and Fixing A11y Issues in Storybook

Once addon-a11y is set up in Storybook, when you execute npm run storybook you should see an Accessibility tab, which will highlight any accessibility violations detected as shown below:

Storybook displaying an accessibility violation on a scrollable div.

Here the add-on is telling me that I have a region of the screen that is actively showing a scroll bar, but the region isn’t keyboard focusable. This means that anyone navigating via a keyboard (such as many users who need accessibility features) will not be able to scroll.

In this case, I can click “More info…” to navigate to the failed rule and view some sample recommended fixes. In this case, I need to add tabindex="0" to the scrollable region so that. Doing that and rerunning the test resolves the issue.

Note that this isn’t going to be as extensive or comprehensive as a browser plug-in specifically designed for accessibility testing, but if you’re already using Storybook, this is an easy way to also use that for quick checks on accessibility.

Accessibility doesn’t just refer to people who need screen readers. Many people suffer from various forms of color blindness. The a11y addon gives us a color filter feature (pictured below) that can simulate various forms of color blindness so you can proof your applications and make sure you’re not hiding information based on color sensitivity.

Storybook displaying a color filter drop down allowing users to customize their visuals to mimic colorblindness

Aria-Live and Content Updates

Aria-live is used to denote an area of the web application which receives periodic updates.

Using aria-live is fairly simple, you add it to any div and specify the politeness. This refers to how urgent the notifications are going to be to the end user.

For example, you’d use <div aria-live="polite"> to only announce events when the user is idle while assertive will be more aggressive.

Setting aria-live isn’t enough, however. You also need to use a LiveAnnouncer to announce the modification to screen reader software.

Take a look at this sample component:

Here on line 20 we inject the LiveAnnouncer into the component via Angular’s dependency injection mechanism.

Next, in the onEntryAdded method starting on line 35 we call out to the liveAnnouncer with our text events. These events will get picked up by the screen reader and presented to the user.

Linting Accessibility

If you want to easily get some degree of auditing into your development practices, you can add some accessibility rules to the tslint.json file that ships with Angular. This will allow you to run accessibility checks during the linting process and can catch some common errors.

To enable this, open tslint.json and add the following rules to your rules collection:

    "template-accessibility-alt-text": true,
    "template-accessibility-elements-content": true,
    "template-accessibility-label-for": true,
    "template-accessibility-tabindex-no-positive": true,
    "template-accessibility-table-scope": true,
    "template-accessibility-valid-aria": true,
    "template-click-events-have-key-events": true,
    "template-mouse-events-have-key-events": true,
    "template-no-autofocus": true,
    "template-no-distracting-elements": true,

Now when you run npm run lint to lint your code, some basic accessibility checks will occur. Note that this is not by any means comprehensive, but even basic checks can help catch things.

Closing Thoughts

Hopefully this article has given you a quick primer or refresher on accessibility in general and some ideas of how to audit and achieve accessibility concerns in Angular.

I am not an expert on accessibility by any means, and I strongly recommend you also consider purpose-built tools like Wave and others if you want to really get serious about auditing your application’s accessibility.

For more up to date details on Angular accessibility, take a look at the framework’s official docs page on accessibility.