Accessibility quick wins

Often as product owners and developers, we hear accessibility and think “it’s a nice to have.” It’s not something we think we should focus on when there are core features that need to be shipped like yesterday. However, the bottom line is that without any concern for accessibility, we are making our products less accessible to everyone, not just to those with a disability.

When we ignore accessibility as a requirement we are creating “accessibility debt.” The accessibility of the site degrades slowly and slowly, like a garden 🌱 that hasn’t been watered in months. Another useful analogy is provided in the book Pragmatic Programmer where the authors state that the degradation of a codebase is comparable to that of a building. It all starts with one broken window:

"One broken window, left unrepaired for any substantial length of time, instills in the inhabitants of the building a sense of abandonment—a sense that the powers that be don’t care about the building. So another window gets broken. People start littering. Graffiti appears. Serious structural damage begins. In a relatively short span of time, the building becomes damaged beyond the owner’s desire to fix it, and the sense of abandonment becomes reality."

The authors warn that this same degradation can happen to code-bases if we're not vigilant in preventing it. This analogy can apply to the codebase as a whole and to accessibility specifically. Instead of waiting until the accessibility of the site needs a complete overhaul causing developers to get buy-in from stakeholders to spend time on it, what if we tended to the accessibility of our site as we go?

The idea here is to present you with some "quick wins" for making your product more accessible to everyone. These are things you can do "as you go." This is not meant to diminish the importance of having full compliance with accessibility guidelines. Ultimately, that is the goal, that's what we should always be aiming for, full compliance. Anything short of that, and you are inevitably guarding your site from being used by someone. However, I've been on enough projects to know that even being mindful of accessibility is a rarity. More often than not, it's completely ignored.

We shouldn't take this all or nothing approach. We can't think "Accessibility? Oh yeah, we can't afford to have that as a concern of ours." The reality is, it is a concern when someone navigates to your site or app, struggles to use it, and then leaves and never returns. At that point it is your concern and affects the business' bottom line.

Like writing documentation or tests, accessibility is often seen as one of those "nice-to-haves" that you'll get around to someday. Let's face it, as developers, we're lazy. We don't want to have to do any extra work. If our project managers are not requesting something be done, we're probably not going to do it. However, this is not a sustainable approach. As makers of the product, the onus is upon us to make experiences that everyone can participate in, or at least not willfully ignore those that experience the product in a more limited way than us. We need to take full ownership of the product.

The idea behind accessibility is this:

Applications should be understandable and usable by people regardless of auditory, visual, physical, or cognitive abilities.

MDN

No one reading this would argue with the sentiment above yet if we don’t take care and do the following things, we’re not adhering to this message. So without further ado, allow me to give you some tips for making your website or app accessible.

Color contrast on text content

This is probably the lowest hanging fruit. Caring about color contrast is being mindful of those who have trouble or a complete inability to distinguish colors from one another. Let's take a look at a common example, buttons:

Looking at these two buttons, it should be fairly obvious which one is easier to read. One of them looks "washed out" and the other has text that's easily distinguishable against the background. However, just using your eye isn't good enough because it doesn't take into account others who see the world differently than you. You as an individual may be able to read the text on both buttons just fine. That's where web standards come in. The web standard for color contrast is in the Web Content Accessibility Guidelines. These are a series of standards set with the intention of making the web more accessible to everyone. The standard defines two levels of contrast ratio for colors: AA (minimum contrast) and AAA (enhanced contrast). The level AA requires a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text (at least 18pt) or bold text. The level AAA requires a contrast ratio of at least 7:1 for normal text and 4.5:1 for large text or bold text. Luckily you don't have to memorize these rules and in practice you probably won't even reference the numbers themselves. There are numerous contrast checkers like this one where you simply input the hex codes for the colors you want to check and instantly know if they meet the guidelines or not, use these anytime you want assurance that your color combinations are accessible.

Passes with a contrast ratio of 8.4

Fails with a contrast ratio of 3.32

Checking color contrast is something that should be done up front when choosing the color palette for your project. It's also something that's easy to keep in the back of your head and straightforward to correct. Basically, if some text is even slightly hard for you to read against a given background it's likely that the colors do not meet these guidelines and need to be updated.

Element inspector 🕵🏻‍♂️

Another easy way to check contrast is to inspect the element in question in Chrome, Edge or Firefox DevTools. Let's look at Google Chrome since it's the most widely used. Open the developer tools (Cmd + Option + i) and make sure you have the element inspector selected:

Google chrome dev tools element inspector

Now, any element you hover over will have a corresponding tooltip giving you styling information and an accessibility indicator. This is what you see when you use the element inspector and hover over an element in Chrome:

Google chrome dev tools

Notice that in the bottom half of the tooltip you get a nice Accessibility indicator. As you can see, the headline I'm hovering over meets the WCAG standard with a contrast ratio of 13.5.

The Accessibility Tree

Okay, so we've looked at a few ways to make sure your color contrast levels are in line with standards. Color contrast is very important for all sighted users, especially those who have some form of color blindness (300 million people worldwide). What about those that are completely blind? As you may know they require the assistance of a screen reader. But how does a screen reader work? How does the browser communicate with the screen reader to tell it what commands and prompts to give? There's an underlying structure that's responsible for this, it's called the accessibility tree.

You've probably heard of the DOM tree, right?

When a web browser parses an HTML document, it builds a DOM tree and then uses it to display the document.

MDN

The DOM is an API we can use as developers to manipulate the visual representation of those elements that the user interacts with. The word visual here is crucial because the DOM tree is really only useful to sighted users. The browser takes this DOM tree and creates an accessibility tree based off of it. In turn, assistive technologies (screen readers) can use this accessibility tree to form a representation of the UI that visually impaired users can understand.

Let's say you write some HTML that looks like this:

<html>
  <head>
    <title>Accessibility quick wins</title>
  </head>
  <body>
    <h1>Color Contrast</h1>
    <p>Some more text</p>
  </body>
</html>

The web browser will first take this structure and create a DOM tree. Here is a diagram to help us visualize it:

Drawing of the DOM tree

Now, a lot of the information in this DOM tree is not useful to visually impaired users. So what the browser does from here is create an accessibility tree based off of this tree keeping only the parts that are useful for assistive technologies. That tree might look something like this:

Drawing of the A11y DOM tree

As you can see, some information and nesting that the DOM needs is not present in this more condensed tree known as the accessibility tree. The topmost block here represents the title of the page, provided in the head tag in our code snippet above:

<head>
  <title>Accessibility quick wins</title>
</head>

This is important information for visually impaired users, it lets them know what the overall message of the content is, like the title of a chapter in a book. So a good rule of thumb is to make sure each page on your website or app has a single title element with text briefly describing the content of the page. This puts us on the path towards writing "semantic HTML".

We'll look more into what semantic HTML is and why it's important in the next section. For now, just understand this flow I've outlined in the 3 screenshots above. It starts with the DOM structure you write, to the DOM tree the browser creates, to the accessibility tree generated from it. Understanding this flow, you can write HTML that's easily and correctly interpreted by the browser so it can form an accurate representation of your website for all users.

As HTML/CSS developers, we are expected to have a solid understanding of the DOM tree and markup. This is our bread and butter, especially if you are primarily a frontend developer like myself. We need to know the different elements and how to manipulate them in order to affect the visual representation that the user interacts with. Yet, the same expectation does not expand to include the accessibility tree, and it should. After all, the only way screen readers can interact with our applications is through the accessibility tree. This is why proper semantic HTML in the DOM is so important. The more rich and meaningful the HTML is, the more rich and meaningful the accessibility tree will be.

Rich, semantic, content

Organizing content in a way that is scannable for both humans and screen readers is another quick win. This really all comes down to semantics in your HTML. For example, we have heading tags in HTML which denote the level of importance that element has on the page. The most common are going to be h1, h2 and h3. Each page of content should have a single h1. That should be the most important heading on the page. For headings that are important but less so than the h1 you would logically use the h2 tag. This may seem obvious, but there are many ways you could create a top-level heading without using an h1 tag. For example, you could wrap the element in a span and style it to look exactly like an h1:

<span style="font-size: 40px; font-weight: bold;">
  <p>Heading</p>
</span>

However, this is bad practice and goes against what HTML is intended for:

HTML should be coded to represent the data that will be populated and not based on its default presentation styling. Presentation (how it should look), is the sole responsibility of CSS.

MDN

We want to use HTML as it's intended. If we don't, we lose out on the accessibility benefits associated with doing it the correct way. This is all about being as explicit as possible when communicating to the browser the purpose your content is serving. There's a host of semantic elements you can use to give more meaning to your content and assist screen readers to the best of your ability.

Layout elements

We must use the HTML elements the way they were intended. Another example is the use of div and span elements. These elements should only ever be used for layout. They do not have any semantic meaning and so give no assistance to screen readers. Often you'll see a clickable div being used in place of a button. This is a misuse of HTML and should be avoidable if at all possible.

Alt text on images

Providing an alt attribute to all of your images is another must-have. The text given to alt is what is shown if the image isn't rendered properly or a screen reader is being used:

<img
  src="http://golden-retriever.photos.jpg"
  alt="Photo of a Golden Retriever dog"
/>

Benefits

Semantic HTML is all about complying with standards set by those who wrote the HTML spec. All browsers, screen readers, and ultimately users base their experiences off of these standards. They are a set of rules we've all agreed upon and build on so that there can be shared pool of meaning across all devices and user agents. When we stray from using semantic HTML, we are going rogue and don't get to participate in that shared pool of meaning. In making sure we use HTML elements the way they are intended, we get to enjoy the following benefits:

  • Gives structure to your content which makes it easier to navigate for sighted users and screen readers
  • Influences the page's search ranking for SEO purposes. When search engines crawl through your page they will be able to pick up on important keywords.
  • Decoupling semantic markup from presentational information means you can apply the presentational information (CSS) to various types of data (HTML).
  • Having a good understanding of accessibility and its importance and how to achieve it makes you a better developer.

ARIA labels

ARIA stands for Accessible Rich Internet Applications. Aria labels are a tool we can use to give semantic meaning to our content when there is no native HTML element available to do so. One of the tools at our disposal is the ARIA "role" attribute. We can attach a role attribute to an element to let assistive technologies know the best way to handle each element. Remember how I said you should never make a div clickable? If you can avoid it, certainly do, but as with most rules in programming, there are exceptions. If you find yourself in one of those exceptional circumstances, you can add an aria "role" attribute to let the screen reader know the element should be treated as a button:

<div tabindex="0" role="button">Sign up</div>

The tabindex here is also necessary. Non-sighted users navigate to different clickable elements by pressing the tab key. So this tabindex does the job of including the div in the tab sequence. So aria roles are used in the case when for some reason you can't use the appropriate HTML element. It's an indirect way of applying semantics to your markup.

Testing

So you think you've done a pretty good job of following best practices and you're confident your site can be deemed accessible. How can you really be sure? If you want to get a quick temperature check on the state of accessibility in your site, use the friendly tool that comes with Google Chrome, Lighthouse.

Google Lighthouse

This is an amazing tool that you can run in Google Chrome for your website or application. Simply open the dev tools in chrome (Cmd + Option + i). Then, on the navigation bar at the top of dev tools click "Lighthouse."

Google Lighthouse in dev tools bar

Next you will be presented with a button to "Generate Report." You can select the categories and devices you want to be included in the report. In this case, if you're just focusing on Accessibility you can select that category:

Generate Google Lighthouse report

You clicked "Generate Report", now wait for Chrome to do its thing...and voilà, you get a fancy readout of your Accessibility score! Not only that, you are presented with some opportunity areas of improvement. Below is the report for this blog as of the writing of this post:

Google Lighthouse report

Well, looks like I could take my own advice and add alt attributes to my images. I hope this illustrates that when it comes to accessibility, much like building a product in general, it's a journey. Hopefully by the time you read this post this score will be up.

It's really handy that google provides this at no cost to developers, take advantage. With tools like this at our disposal it makes it harder to justify having a poor accessibility on your site. Really I'm just lecturing myself at this point 🙈

Wrapping up

To recap, we began by understanding why we should care about accessibility. We then explored some techniques like proper color contrast and how to verify it. We learned about the accessibility tree and how to write semantic HTML so we can interface effectively with it. Finally, I left you with a way to test the accessibility on your site using Google Lighthouse.

Now, of course this is not an exhaustive tutorial on writing perfectly accessible websites. I just wanted to spread the good word about the importance of accessibility and to get you thinking like a screen reader. I hope I've demonstrated the significance of having good accessibility, it's really all about empathy. Go forth and prosper with some of these quick wins and tips and hopefully we will continue to create better experiences, for everyone.