Making Accessibility More Accessible

Get more team members involved with accessibility by sharing tools they'll actually use. A11y tools for design, development, QA, and CI/CD.


Austin Gil

2 years ago | 11 min read

Every person I’ve worked with has agreed that making the web more
accessible is a good thing. We don’t want to disservice any of our

However, accessibility
is nuanced, the work is not always straight forward, and responsibility
can be unclear. After all, building websites requires many steps, and
accessibility is impacted by the decisions at each stage; design,
development, content creation.

It would be great if everyone was an accessibility expert, but that’s
probably not going to happen. Becoming an expert is a full time job.

If you’re lucky, you might have one solid person on the team who advocates and educates. But that is not good enough.

So in addition to (not instead of) having dedicated people thinking
about accessibility, we must provide tools that make it easier for teams
to do the
right things and/or harder to do the wrong things.

Ideally, we will meet be people where they work by integrating into the tools they already use. It’ll makes it much more likely that they actually use them.

Let’s make accessibility work intuitive where it needs to be and automatic where it can be.

Some Background on Accessibility

The governing body for accessibility standards is the Web Accessibility Initiative (WAI). They produce and maintain the Web Content Accessibility Guidelines (WCAG) which outline standards for web accessibility (in case that wasn’t already obvious).

A different organization called WebAIM publishes an annual report called “The WebAIM Million“. It’s focus is to measure the accessibility of top 1 million websites and report the trends they find.

According to them, as of February 2021, we’re not doing a great job.

Across the one million home pages, 51,379,694 distinct accessibility errors were detected—an average of 51.4 errors per page

Here are the most common issues discovered, along with the percentage of pages that they occurred on.

  • Low contrast text: 86.4%
  • Missing alternative text for images: 60.6%
  • Missing form input labels: 54.4%
  • Empty links: 51.3%
  • Missing document language: 28.9%
  • Empty buttons: 26.9%

It’s important to note that these numbers are based on WCAG
conformance metrics that can be automatically measured by machines.
Those metrics don’t necessarily account for
all accessibility issues. Nonetheless, it’s helpful to know where we stand.

With all that in mind, let’s take a look at the things we can do to address these issues across our teams.

Accessibility Tools for Designers

The earliest stage to start addressing accessibility issues is probably the design phase.

The work done before design is low fidelity and likely to change. But
design decisions are more likely to stick so it’s a good early stage to
catch issues.

Unfortunately, most accessibility issues stem from code, not design.
But if we look back at the list of most common issues, we will see that
the number one problem is related to design: low contrast text.

According to the WCAG, the criteria to pass AA standards for color contrast is…

The visual presentation of text and images of text has a contrast ratio of at least 4.5:1, except for the following:

Which means, if you were creating a design with a badass background color like, oh, I don’t how, how about #BADA55, in order to pass AA standards, your foreground text color would have to be…

Well, I have no idea. I’d be surprised if anyone could tell you off the top of their heads. And that’s the point.

It’s very difficult for designers to just know what color combinations are acceptable.

There are plenty of tools to help you compare two colors. shows plain and simple how two colors compare. is similar and has the added features of showing common visual impairments.

These tools are great, but they aren’t what I mean by meeting people where they are. I don’t want to introduce new tools, I want to integrate into existing workflows.

The best tool I can recommend for the job is Stark. It offers accessibility tooling plugins for Figma, Sketch, and AdobeXD. With it, designers can begin to address accessibility issues without changing context.

That’s a good thing. It won’t solve problems over night, but it has a
better chance than asking someone to step out of their flow.

In addition to that, there are a couple other tools I recommend. They
don’t integrate into design tools (at least no to my knowledge), but
they do help when dealing with specific problems.

If you are starting to design a color palette from scratch for generic colors (not brand colors), Accessible Palette
is a good start. It provides several common colors and permutations
along with the WCAG ratings for text on top of those colors.

If you already have a set of predefined colors (like brand colors) Accessible Brand Colors let’s you add colors and presents a gird layout showing which combinations pass WCAG conformance.

Finally, it’s quite common that you want to use a brand color as a
background, but the combination with the text color is not accessible.
Accessible Color Generator
is an awesome tool that will suggest a close alternative color to use.
Many times, I can’t really tell the difference (then again, I’m not a

Accessibility Tools for Developers

Code has the largest impact on accessibility which means developers carry the most responsibility.

Once again, several tools can take markup or a URL and spit out an accessibility report. WAVE by WebAIM
is probably the best I’ve found, but it has the same flaw as most color
contrast checkers. It relies on developer breaking out of their flow to
use a different tool.

Instead of asking our developers to go to the accessibility tools, we can bring the accessibility tools to the developers.

Editor Plugins

For developers using VS Code, for example, there are two excellent plugins that will notify the developer of any accessibility issues with their code. axe Accessibility Linter and webhint
have helped me catch and fix many errors without having to keep
everything in my head. In fact, they’ve even help teach me about certain
accessibility issues I didn’t know about.

Editor extensions are great to get some developers on board but they
aren’t without flaw. To have the same impact across the team would
require that everyone uses the same IDE with the same extensions
installed and the same settings. Sure it’s possible, but I think that
does more harm than good. I prefer that sort of thing to be opt-in.

Frontend Frameworks

Modern frontend frameworks have adopted a component-based paradigm.
As a result of building everything as components, we can tackle
accessibility needs in a single place and address accessibility wherever
the component is used.

Take, for example, a component we’ll call AppInput that wraps an <input>
tag. We can use this component to enforces that all the necessary
markup is needed to make an accessible input, and any developer that
uses that component will get those benefits without needing to be an
expert. That’s great!

For example, we may want to enforce that every input has a label.
Unfortunately, as component authors it’s not possible for us to know
what an inputs label will be. That is for the component consumer to
decide when they add the AppInput component to a page.

Most component-based libraries also have the concept of “props” as a way to pass data to the component like this <AppInput label="my label" />. In this example, label is a prop.

One thing we can do to enforce accessibility is log a warning to the
JavaScript console any time out component is implemented without a
label. We can do that with prop validation.

Vue has prop validation built in and React has the prop-types library. You could use TypeScript as well, but it’s not quite as robust.

In addition to validating props, we can provide optional props with
default values. If the developer consuming the component wants to use
the prop, they may. Otherwise it will fall back to a default.

A good example for this use case is an id attribute. An input should always have an ID attribute. It’s the best way to attach a form to a label.

However, we don’t really need to think of a new ID for each input. We
can use JavaScript for that. If the consuming developer provides an ID
for the input, we should obviously respect that decision and use it. But
if they don’t, why not generate one randomly and use that? After all,
browsers and assistive technology don’t care if an input has an ID of
“first-name” or “dg234d”.

Finally, it’s not always necessary to build the components from
scratch. There are several component libraries out there that are ready
to go and have already implemented accessible markup or functionality.

Several of the more popular libraries have already accounted for
that, but if you are looking for completely unstyled solutions that
offer more design flexibility, here are some options:


This last part focuses on a11y.css
and the concept is super cool. It’s a CSS library that highlights
elements on a page that may have accessibility issues. So it basically
let’s the browser engine do the work for you.

Obviously you don’t want to include this sort of CSS library in your
production website, but I can think of two ways it could be used.

If you have a build process that’s capable, you could check whether
the environment is production code or development code and only include
the library during production builds.

Or, you could find a way to include the library only on a staging
site. That’s probably even better because it would mimic production more

Accessibility Tools for QA & Code Review

Some companies don’t want their code being automatically deployed to
production without someone’s eyes checking that everything still looks
good. To make sure things are in place, we have a few options:

  • Code review: someone that did not write the code reviews the code and approves it before it gets merged.
  • Staging environments: deployments that mimic production environments as closely as possible, but at a different location.
  • QA teams: engineers that manually test to make sure everything looks and works as intended

Code review provide a great place to look for accessibility issues,
but not all teams have a dedicated accessibility expert to review all
code. Or maybe they do, but there is a lot of code to review.

Fortunately, there are tools like Accesslint
which run accessibility checks on your code during pull requests. It
can be a nice, easy way to add some automated checks in addition to
human checks.

We can also give our QA engineers some help by sharing axe DevTools by Deque.
By it’s nature, manual testing happens in the browser, so it’s very
convenient to have a browser extension that can test accessibility for

Accessibility Tools for CI/CD & Deployment

We’ve looked at a lot of tools that help humans on our teams improve
accessibility but those tools have one flaw; they rely on humans.

As mentioned before, the tools we introduce should be opt-in choices.
That’s great for the team, but unfortunately it leaves openings for
inaccessible code to get into our projects.

To address that, we can shift from tooling at the edges (team
members) to tooling at the central source (source code in a shared

By integrating a Continuous Integration (CI) and Continuous Delivery
(CD) pipeline to our code repository we can run tests that check for
any accessibility issues any time a change is pushed. If we also use the
CI/CD tools to automatically deploy our websites, we could also prevent
automated deployments if our tests fail.

How awesome is that!?

(This also applies to other types of test: unit, integration, etc but we’re focused on accessibility)

The first thing we’ll want to do is set up automated accessibility
testing. Most accessibility testing tools will use some sort of
synthetic, or “headless” browsers.

Headless browsers are tools that imitate the rendering behavior of
standard browsers without any visual representation. We can use them to
“open” our website and the headless browser responds with the same code
as a standard browser. You just don’t see anything.

It’s much faster and allows us to write tests against out frontend
code. This makes it much easier to test whether markup that SHOULD be on
a webpage actually arrives.

Most headless browsers work well enough for enforcing things in the
markup, but they generally fall short for things like color contrast.

Cypress is an exception.

Cypress is different because it ships an electron app that can launch
an actual browser and automatically drive it through your tests. In
addition to watching your tests run, you can tell Cypress to run in
headless mode, which is not visible but can still detect the colors on
your page.

Cypress itself does not know anything about accessibility though, but there is a plugin called cypress-axe by Deque (notice a pattern?) that can be used check for a11y issues within tests.

With everything hooked up, we can begin adding accessibility tests to
our applications. One that checks the homepage might look like this:

describe('Homepage', () => {
it('is accessible', () => {

Note that this test checks the entire page. If you are working with
component frameworks, they also offer the ability to test individual
components. See the
component testing documentation here.

Once we have our tests written, we can trigger the test command from a
CI/CD pipeline. Your CI/CD tool may differ, but here is an example for a
GitHub Action that runs Cypress tests. Assume the package.json file contains a script called "test" that runs the "cypress" CLI command.

name: Test

branches: [ production, staging ]
types: ['opened', 'edited', 'reopened', 'synchronize']

runs-on: ubuntu-latest
- name: Checkout source code
uses: actions/checkout@v2
- name: Install dependencies
run: npm ci
- name: Run Cypress End-to-End tests headlessly
run: npm run test -- --headless

Here are some more handy links if you need more documentation around this:

The big benefit to doing thing this way is that it completely removes
the tooling requirements from individuals. The folks that want to opt
in to tooling like editor plugins may do so to get the help while they
write. Those that prefer not to not may opt out. But accessibility will
be checked regardless.


I hope you found this article helpful and will take additional steps
to make the web a more accessible place. I’ve found these tools to work
well for improving accessibility without getting in the way.

However, there is a major caveat I want to reiterate. Tooling and
automated tests have gotten really good, but I can’t see a scenario in
the near future where it can replace user testing.

Even if your automated tests pass WCAG guidelines 100% it does not
always mean your website is accessible. There are many things that
cannot be caught automatically.

There’s an interesting article by Manuel Matuzovic called “Building the most inaccessible site possible with a perfect Lighthouse score” that takes a funny look at this. It’s worth reading.

The best advice I can give for that is to gather real data about your
users, what devices they are using, and try to provide the best
experience possible for everyone.

But if we can use tools created by accessibility experts means more
people on the team can find bugs without having to be experts

Heck, even for the experts, using robots can greatly speed up the process.

Thank you so much for reading. If you liked this article, please share it, and if you want to know when I publish more articles, sign up for my newsletter or follow me on Twitter. Cheers!

Originally published on


Created by

Austin Gil

Over the last ten years, I’ve built projects for award-winning agencies, innovative tech start-ups, and government organizations. Today, I create cool stuff for the web and share what I learn through writing, open-source, YouTube and Twitch, The Function Call, speaking and workshops.







Related Articles