Accessible HTML in Angular2 applications (and not only)
The reason to make an application accessible is to warranty that the web is an inclusive place available for every user.
Accessibility is for everyone
Yes, accessibility is for everyone. Let’s see some examples why:
- A power user navigating with the keyboard through an application will make use of focusable and tab reachable elements.
- A tired person after a workday would need extra effort to read a low contrast or small font size text
- A visually impaired person will make use of a screen reader
Whether working on an Angular2 stack or not, HTML is the starting point to make an application accessible.
Today JS frameworks as Angular and React are such powerful tools that developers often forget the HTML basics. And those basics are the elements for the user to interact with: buttons, links, form controls… Accessible HTML is not difficult to write, and it is even easier if we start using semantic markup.
In this post we will see why writing accessible HTML has clear advantages from the developing point of view. We will do so implementing of two UI elements: a button, and an input with a suggestions list.
It’s not unusual to find a button as in the following example in JS dependant applications:
<span class=”button” (click)=”handleClick()”>Click here</span>
A visual browser displaying this code once rendered will show an element which looks like a button thanks to the styling provided through the class. While it looks like a button, it won’t be keyboard accessible as browsers focus by default buttons, links and form controls.
The avdanced version of the previous code could be something like this:
<span class=”button” (click)=”handleClick()” tabindex=”0”>Click here</span>
tabindex attribute we are telling the browser that this element should be reachable and thus focusable when using the keyboard to move around the application. Though this seems to solve an important issue, there is something important left, this button-like element does not react when hitting the enter key.
The experts version of this button, which I remember once more that it’s not an HTML button, will try to solve the issue by adding an event handler which will call the
handleClick method when the user presses enter on the keyboard.
<span class=”button” (click)=”handleClick()” (keydown.enter)=”handleClick()” tabindex=”0”>Click here</span>
There is still more to come: A button should also accept space key strokes. To handle space pressing a third event handler should be added to our code:
<span class=”button” (click)=”handleClick()” (keydown.enter)=”handleClick()” (keydown.space)=”handleClick()” tabindex=”0”>Click here</span>
For this element to achieve a button behavior it should be understandable as a button by assistive technologies. To do so, ARIA attributes should be used. Otherwise, this element appearing as a button for all visual browsers, being focusable and pressable using both point devices as well as the keyboard, would not work.
<span class=”button” (click)=”handleClick()” (keydown.enter)=”handleClick()” (keydown.space)=”handleClick()” tabindex=”0” role=”button”>Click here</span>
And yet there is the ultra advanced developer button version:
<button type=”button” (click)=”handleClick()”>Click me!</button>
This button is surprisingly a button! And is a great element both for developers and users. Semantically it is a button and this means the information is properly structured, assistive devices will automatically recognize it as a button and it will be a focusable element. So, yes. It is an accessible element. Besides, with just one event handler it will react to the user input it should react to: clicks, enter and space key strokes.
Great, isn’t it? So, where is the sense of implementing a button which is not button? There is no sense at all, eventhough it is something widely exemplified in the web.
Input with suggestions
Let’s take a look to another element, an input which offers a list of suggestions. This component will display a list of available options as soon as the user starts typing. We will focus in the very input and displaying the options and not on the way to provide the front with the available options.
First thing, we need is an input and the options list. Having a list of options to display, it seems natural to add a list which will show up when the user starts typing. So the starting code should look like something like this:
<input type="text" id="autoComplete"> <ul> <li>Mary</li> <li>John</li> <li>Peggy</li> <li>Brandon</li> <li>Ann</li> <li>Theresa</li> <li>Lewis</li> <li>Carol</li> <li>Emma</li> <li>Andrew</li> <li>Robert</li> <li>Victoria</li> </ul>
For this code to start working and be accessible we would need to implement:
- Event handlers for keyboard interaction
- Make the different elements focusable
- Add ARIA elements to make a meaningful structure for assistive technologies to recognise unsemantic code (for this component)
But we will not implement this now. Let’s just jump to a version based on the use of the
HTML element. The reason for using this element is that it provides a set of suggestions for a control (after the datalist element W3C specification), in this case the input.
<input type="text" list="options" id="autoComplete" class="greeter__autocomplete"> <datalist id="options"> <option value="Mary"> <option value="John"> <option value="Peggy"> <option value="Brandon"> <option value="Ann"> <option value="Theresa"> <option value="Lewis"> <option value="Carol"> <option value="Emma"> <option value="Andrew"> <option value="Robert"> <option value="Victoria"> </datalist>
The way to bind both input and datalist elements is using the
id value of the
datalist element as the value of the
The use of
datalist saves a lot of developing time and is accessible out of the box. Browsers supporting this element provide all the logic that would be needed to make the suggestions dropdown functional.
All modern browsers but Safari support this implementation of an input with a list of suggestions based on the user input. There is a fallback proposed in the specification for those browsers (Safari or legacy browsers) not supporting the datalist element. This fallback consists in the use of a
select inside the
datalist. This way, the browsers supporting the
datalist element will just ignore the
select while the ones in which is not supported will render the options in a similar fashion to the native
It is important to remark that there are some downsides when using the
datalist. Its implementation doesn’t work properly with long lists, IE sends the selected option once chosen from the list (as reported in Can I use) and there is also the less than optimal fall-back displaying select next to the input.
For what we have just seen, the use of the
datalist element may be considered as a progressive enhancement which offers some extra functionality, the suggestions list in this example, to the users which have the proper technology while not cutting down on the main functionality, the input.
But, if we face a situation in which we are required to implement the suggestions list so it is available for every user, a custom implementation should be used.
In this post we have seen how using semantic HTML makes the web an inclusive place, accessible for everyone, while making the life easier to the developers by saving developing time.
The two examples we have seen are slightly different and show what is the reality of semantic HTML support:
- Elements as
buttonare supported widely by the different browsers
- Some other semantic HTML elements as
datalistare not as widely supported and maybe used as progressive enhancement
When the functionality of a semantic HTML element is not widely supported we might need to make use of a custom implementation. Which we will see with the input with suggestions list in a future article.