CTEC2712 Web application development

Lab exercises are designed to help you gain practical experience with web technologies. You should elaborate on these exercises to confirm you understand and deploy the learning you find here in your own code.

Accessibility

In this module we consider accessibility as a foundational design goal for building high quality HTML documents representing our application interface.

Considering the accessibility of your HTML will typically lead to a better overall design and will often lead to a document that is easier to style for the browser. Moreover, if your site doesn’t take accessibility into account, then you are preventing users of assistive technology from accessing your content.

What do we mean by accessibility?

If software can understand the semantics (i.e. the meaning) of your document then it can provide this additional information to the user as necessary. For example, assistive technologies need to be able to access your document structure so they can provide users with navigation tools.

Accessible Rich Internet Applications

When building HTML documents, there are techniques we can use to structure the content with the proper semantics and include additional information. These are known as the Accessible Rich Internet Applications standards (or simply ARIA for short). ARIA provides us with attributes we can add to our HTML elements to give assistive technologies more information.

In particular, the role attribute can be used to describe the semantics of widgets and structural elements in your page. Often used with other attributes to provide more detail.

We can add the role attribute manually to any element. A good example is the heading role which indicates to assistive technologies that an element should be treated like a heading.

We can use any element (such as a <div>) to create a heading like this.

1
<div role="heading" aria-level="1">This is a main page heading</div>

the aria-level attribute tells the assistive technologies which part of the page structure the element represents. However, the same result can be achieved by simply using the correct semantic element, in this case an <h1> element.

1
<h1>This is a main page heading</h1>

The above code examples are semantically identical but the second example is clearly more convenient, easier to read and generally much better.

For the most part, using semantic HTML elements (e.g. <header>, <ul> or <section>) rather than meaningless elements (e.g. <div> or <span>) will automatically provide the necessary ARIA roles to describe the structure of your document for assistive technologies to parse up your content and present it in a meaningful way to users.

Always use the correct semantic elements for your content. It’s not difficult and there are often multiple choices. Make sure you only use generic elements such as <div> or <span> elements when they don’t carry any semantic meaning.

Examples

To explore these examples in detail you will need to activate screen reader software.

Windows has a built in screen reader known as narrator which can be started like any other programme.

On ubuntu the screen reader can be accessed from the accessibility menu.

accessibility menu on ubuntu

The accessibility menu can be activated in settings under accessibility.

There are three very common cases where accessibility concerns impact your choice of HTML code directly.

  1. Images and alternative text
  2. Basic page structure
  3. Labelling inputs

We will now attempt to use a screen reader to demonstrate the impact of using the correct semantic elements and adding the necessary attributes.

Images and alternative text

Images are added to a site using the <img> element. The <img> element must include a src attribute pointing to the url of an image file.

Create the following document and load it in the browser.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Accessibility examples</title>
</head>
<body>
    <header>
        <h1>Images</h1>
        <p>
            Images are a good example of content where accessibility concerns are an important factor.
        </p>
    </header>
    <main>
        <h2>An example of poor accessibility</h2>
        <p>
            The following image is essentially invisible to a screen reader.
            We can tell there is an image, but we have no idea what it is showing.
        </p>
        <img src="https://placekitten.com/200">
    </main>
</body>
</html>

In the browser, the image shows perfectly normally.

However, the document is actually invalid. Try it in an HTML validator and you should get an error and a link to the W3C images tutorial.

For a valid document and for accessibility, <img> elements must have an alt attribute which provides a text description that can be used as an alternative to the image for those who cannot see it.

The W3C images tutorial contains lots of good examples of alternative text for various types of images.

The alternative text will be announced by a screen reader. An image with no alt attribute will be announced as “unlabelled image” within the flow of the document.

Try accessing the document with a screen reader. The experience is frustrating, the image is acknowledged but we have no information about it.

If we add an empty alt attribute then the image is effectively ignored by the screen reader. This is an acceptable strategy where images are used as meaningless decoration.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Accessibility examples</title>
</head>
<body>
    <header>
        <h1>Images</h1>
        <p>
            Images are a good example of content where accessibility concerns are an important factor.
        </p>
    </header>
    <main>
        <h2>A hidden image</h2>
        <p>
            This image has an empty <em>alt attribute</em>.
            Notice the impact this has on the screen reader.
        </p>
        <img src="https://placekitten.com/200" alt="">
    </main>
</body>
</html>

The page is identical in the browser, but the document will now validate.

To the screen reader, the image is gone.

Usually we want the user to know there is an image and we want them to have a sense of what the image shows. For this, we can add a simple description as the alt attribute. The description will be announced by the screen reader when the image is reached in the document.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Accessibility examples</title>
</head>
<body>
    <header>
        <h1>Images</h1>
        <p>
            Images are a good example of content where accessibility concerns are an important factor.
        </p>
    </header>
    <main>
        <h2>An example of good accessibility</h2>
        <p>
            This next image is much better because it has a non-empty <em>alt attribute</em>. 
            The alternative text briefly describes the image for users who cannot see it.
        </p>
        <img src="https://placekitten.com/200" alt="a random kitten, looking cute">
    </main>
</body>
</html>

Again, this has no effect in the browser, the three sites appear identical.

However, to the screen reader there is a big difference between the three options.

Try it, the image is announced by the screen reader and the user gets the best experience.

So make sure you add a sensible alt attribute for every image in your document. Add empty alt attributes only for images which are not part of the content.

Basic page structure

Imagine a large document on the web, something like this page but even larger. The user should be able to quickly scan through the various sections and headings to find what they are looking for. However, using very bad practice, it’s possible to create a document that is impenetrable.

Here’s a good example of what not to do. Using all the wrong elements to structure our page.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Poor</title>
</head>
<body>
    <div id="container">
        <div>The main page heading</div>
        <p>This article is about showing a page structure.</p>
        <div>Introduction</div>
        <p>An introductory text.</p>
        <div>Chapter 1</div>
        <p>Text</p>
        <div>Chapter 1.1</div>
        <p>More text in a sub section.</p>
    </div>
</body>
</html>

It is difficult to follow the structure of the resulting page because the headings are not visually distinct. The same is true when using a screen reader.

We can add the necessary ARIA heading roles explicitly. By giving each heading an aria-level attribute, we are providing a structure that can be announced by screen readers.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Better</title>
</head>
<body>
    <div id="container">
        <div role="heading" aria-level="1">The main page heading</div>
        <p>This article is about showing a page structure.</p>
        <div role="heading" aria-level="2">Introduction</div>
        <p>An introductory text.</p>
        <div role="heading" aria-level="2">Chapter 1</div>
        <p>Text</p>
        <div role="heading" aria-level="3">Chapter 1.1</div>
        <p>More text in a sub section.</p>
    </div>
</body>
</html>

This change makes a big difference to assistive technologies, but the page would need some additional styling to reveal the structure visually.

The above may seem complicated. Luckily, we can achieve exactly the same result by using the proper semantic elements. In this case the <h1> to <h6> elements all provide the heading role and have the aria-level baked in.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Good</title>
</head>
<body>
    <div id="container">
        <h1>The main page heading</h1>
        <p>This article is about showing a page structure.</p>
        <h2>Introduction</h2>
        <p>An introductory text.</p>
        <h2>Chapter 1</h2>
        <p>Text</p>
        <h3>Chapter 1.1</h3>
        <p>More text in a sub section.</p>
    </div>
</body>
</html>

Not only is this version easier to write, it also has both visual and semantic meaning built in so it provides all users with information about the structure of the page.

If we want to add more structure still, we can bring in some more content sectioning.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Structured</title>
</head>
<body>
    <header>
        <h1>The main page heading</h1>
        <p>This article is about showing a page structure.</p>
    </header>
    <main>
        <section aria-labelledby="intro">
            <h2 id="intro">Introduction</h2>
            <p>An introductory text.</p>
        </section>
        <section aria-labelledby="ch1">
            <h2 id="ch1">Chapter 1</h2>
            <p>Text</p>
            <h3>Chapter 1.1</h3>
            <p>More text in a sub section.</p>
        </section>
    </main>
</body>
</html>

The above example has added a <header> around the main heading and description. The rest of the document is wrapped in a <main> element. The introduction and chapter 1 are wrapped in <section> elements to give them each a region role. In order to do this properly, we needed to label each section, this can be done using the aria-label attribute to provide a label directly, however, since we have out <h2> elements, we can use these as the labels by giving them id attributes and using the aria-labelledby attribute on our <section> elements.

We have added a bit more semantic structure to the document and this has had an impact on what a screen reader sees.

However, notice that visually, the site still looks exactly the same.

This extra structure in the HTML has a few other benefits. Firstly, it helps the HTML author to visually navigate around the document because the indentation level is closely related to the document structure. Text editors such as vscode allow elements to be optionally folded and unfolded, this can become important with large and complex documents.

The additional elements can also be used for styling the page with CSS.

We will investigate styling in a lot more detail in upcoming exercises

Accessible inputs

The <input> element is used to receive user input. Adding an input element is as simple as this.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Basic</title>
</head>
<body>
    Enter your name: <input><br>
    Enter your age: <input><br>
</body>
</html>

The result is a box which allows users to enter a name.

Try navigating the simple page with your keyboard. Using the tab key will enter the next field. Holding shift and pressing the tab key will enter the previous field.

Assistive technologies are often smart enough to guess that the text should be linked with the input.

However, using a <label> element and associating it directly with the input provides more assurance and gives benefits such as increasing the clickable area.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Basic</title>
</head>
<body>
    <label for="name">Enter your name:</label>
    <input id="name"><br>
    <label for="age">Enter your age:</label>
    <input id="age">
</body>
</html>

In more complex scenarios, accessibility can be very poor indeed. For example, if we want to add text to the left of a radio button like this.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Poor</title>
</head>

<body>
    <span>Red</span>
    <input type="radio" name="colour"><br>
    <span>Green</span>
    <input type="radio" name="colour"><br>
    <span>Blue</span>
    <input type="radio" name="colour"><br>
</body>

</html>

The result can be very confusing for screen reader users because the assumption is that text will com after a radio button.

Using a screen reader, select the radio button set with tab and then use the up and down arrow keys to navigate the options. Use the space bar to select an option. Notice a problem?

We can improve things by labelling each of the inputs more explicitly.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>OK</title>
</head>

<body>
    <label for="red">Red</label>
    <input type="radio" name="colour" id="red"><br>
    <label for="green">Green</label>
    <input type="radio" name="colour" id="green"><br>
    <label for="blue">Blue</label>
    <input type="radio" name="colour" id="blue"><br>
</body>

</html>

To a typical browser user, there is no visible change. However, the impact of this upgrade is massive in terms of making sense to software. The relationships between the labels and the radio buttons has been made explicit.

Make sure you try this with a screen reader.

We can make a further improvement by labelling the entire group with a <fieldset>.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Good</title>
</head>

<body>
    <fieldset>
        <legend>Colour</legend>
        <label for="red">Red</label>
        <input type="radio" name="colour" id="red"><br>
        <label for="green">Green</label>
        <input type="radio" name="colour" id="green"><br>
        <label for="blue">Blue</label>
        <input type="radio" name="colour" id="blue"><br>
    </fieldset>
</body>

</html>

Now, when the user navigates around the options, the screen reader knows exactly what its doing.

This time, the addition also makes a visible difference, arguably an improvement.

Conclusions

We have seen that the structure of your HTML document determines how well the document can be interpreted by software such as browsers and screen readers. Taking care to provide a high quality structure to your HTML, independent of any styling considerations, can produce a much better user experience, not only for users of assistive technology, but also to users who e.g. prefer to use the keyboard for navigation.

Now take some time to build out your own HTML documents taking care to consider accessibility.