Introduction

When approaching Web Accessibility, I was a bit lost. How to make my website accessible ? Where should I start ? Being a newbie it seemed hard to achieve perfection in terms of Accessibility.

The Web Content Accessibility Guidelines (WCAG) 2.0 covers a wide range of recommendations for making Web content more accessible. All guidelines are accessible on w3.org.

I followed these “Easy Checks” guidelines:

Easy Checks – A First Review of Web Accessibility

To know more about dev tools that I used:

Dev tools to start with Web Accessibility

Set up: Create a form

I created a simple form in React to subscribe to a newsletter. I recommend creating an app as it is easier to use web extensions or browser options than with CodeSandbox. It makes it easier to perform all tests.

npx create-react-app myapp

Source code can be found on CodeSandbox.

New Form

What to check for

Title

✅ Check that there is a title that adequately and briefly describes the content of the page.

I added a title in my index.htmlfile:

<title>Newsletter subscription</title>

✅ Check that the title is different from other pages on the website, and adequately distinguishes the page from other web pages.

I only have one page


Image text alternatives (“alt text”)

✅ Every image has alt with appropriate alternative text.

I don’t have any image in this form. If I had one, I could add a alt="with a description" to the image tag as it has to describe the information on the image to a person who can not see the image. But I could also have a alt="" if the image is not important for understanding the content of the form.


Headings

✅ The page has a heading. In almost all pages there should be at least one heading.

✅ The heading hierarchy is meaningful. Ideally the page starts with an “h1” — which is usually similar to the page title — and does not skip levels.

Indeed, I have a h1heading

<h1>Subscribe to my awesome newsletter</h1>

✅ All text that looks like a heading is marked up as a heading.

✅ All text that is marked up as a heading is really a conceptual section heading.

I only have one heading in this form, so I am compliant :)

✅ To check headings with WebDev toolbar

With the “WebDev toolbar” > Information > See document outline, I checked the heading of my page. When several heading, it shows a clear view of heading hierarchy.

Document Outline


Contrast ratio (“color contrast”)

Web pages should also have a minimum contrast by default: a contrast ratio of at least 4.5:1 for normal-size text.

There are basically three ways to check contrast, each with strengths and weaknesses (see guidelines for more details)

  1. Table with contrast ratio: Use a web extension
  2. Eye-dropper to select colors: Use a color-dropper extension and check the color with WebAIM
  3. Turn off color

I used the WCAG Color contrast checker Chrome extension to check the contrast ratio.

WCAG Color contrast checker

This check confirmed that the contrast ratio were respected: they all pass for AA and AAA levels.

WCAG details AAA level

For example, the contrast for the text of the form (grey above white) is a ratio of 9.66:1, which is above the minimum ratio required.


Resize text

✅ All text gets larger.

In Firefox, select View > Zoom > Zoom Text Only. There are extensions in Chrome to do the same thing.

Then zoom, it should increase the text. Below, I zoomed to 200%.

Firefox Zoom Text only

❌ Text doesn’t disappear or get cut off.

I noticed that when zooming the text was cut off at the top, and I could not scroll up to read it.

This was due to a fixed CSS height. I replaced it with a margin-top

✅ Text, images, and other content do not overlap.

✅ All buttons, form fields, and other controls are visible and usable.

✅ Horizontal scrolling is not required to read sentences or “blocks of text”.


Keyboard access and visual focus

Tab to all: I can tab to all elements (input, form fields, button)

Tab away: I can tab away from all elements that I tabbed unto.

Tab order: The tab order follow the logical reading order (top to bottom)

Visual focus: Check that the focus is clearly visible as you tab through the elements, that is, you can tell which element has focus, e.g., links have a gray outline around them or are highlighted.

Tab Focus

All functionality by keyboard: I can do everything with the keyboard (I don’t have functionalities only available with mouse hover)

Indeed, I can use the up and downs arrows to select the dropdown options and the space key to select the terms of service.

Drop-down lists: I can move through all the options of the drop-down list without triggering an action


Forms, labels, and errors

Labels

❌ Check that every form control has a label associated with it using ‘label’, ‘for’, and ‘id’.

<label>Name: {name}</label>
<input id="name" type="text" value={name} onChange={onChangeName} required />

I missed the for attribute for the label, so I had to adapt like so:

<label for="firstname">Name: {name}</label>
<input id="name" type="text" value={name} onChange={onChangeName} required />

✅ Check that the labels are positioned correctly. For left-to-right languages, labels should usually be:

  • Left of text boxes and drop-down lists.
  • Right of radio buttons and checkboxes.

I am very surprised of this guideline as my label is not positioned left to the text box mais above.

Top box

They give survey examples where the label is also above (here), so I would leave it that way as I prefer this design, and it seems it does not have impact on accessibility.


Required fields and other instructions

❌ Check that any fields that are required/mandatory are clearly indicated.

The mandatory fields were not clearly indicated in the first version of the form.

Missing requirement

The indicator does not have to rely on color alone, I had to add a <span>(required)</span> attribute to each label to make it clear.

<label for="firstname">Name: {name}<span>(required)</span></label>
<input id="name" type="text" value={name} onChange={onChangeName} required />

Top box

✅ Check that any instructions for completing the form are before they are needed.


Error handling

✅ Check that clear and specific guidance is provided to help people understand and fix the error.

✅ Check that the errors are easily findable. Generally it is best if the error messages are before the form, rather than after the form.

✅ Check that the fields without errors are still populated with the data you entered.

This section is a bit more complicated. The errors displayed in my form are not explicit enough. It was ok but it wasn’t explicitly describing what was missing.

Before error

There is a small tutorial on React form to make it more accessible.

I remove the required attribute

    <label htmlFor="email">
        Email: <span>(required) </span>
    </label>

    <input
        name="email"
        type="email"
        id="email"
        value={email}
        onChange={onChangeEmail}
        required
    />

to write a more explicit error message

    <label htmlFor="email">
        Email: <span>(required) </span>
    </label>
    {errors.email && errors.email.type === "required" && (
        <span>Email is required</span>
    )}
    <input
        name="email"
        type="email"
        id="email"
        value={email}
        onChange={onChangeEmail}
        aria-invalid={errors.email ? "true" : "false"}
        ref={register({ required: true })}
    />

Now, the error clearly indicated what is missing. I could improve it with some CSS.

After error

I added these improvements to each input.

For the last checks, Moving, Flashing, or Blinking Content and Multimedia (video, audio) alternatives, this form does not apply to these guidelines as I don’t have any audio or interactive media.

Conclusion

It requires conscientious work to check a website accessibility. But W3C provides a lot of documentation to make the process easier !

I hope this article helps. Do not hesitate to reach out for feedback. As a beginner in Web Accessibility this may not be perfect.

Updated: