How can you improve the accessibility of your design system?

  • Updated

What we mean by accessibility

In the web community, the topic of accessibility comes around every so often, and we’d like to hope that collectively we’re improving with this all the time. It’s something we need to continually educate ourselves about and make part of our practice as designers or developers. Michelle did a great job explaining what accessibility is and busting some common myths, so I wanted to expand upon it a little to how we can apply it to our design systems.

Creating or working with a design system can present a real opportunity to embed good practices like accessibility into your output, from color combinations for good contrast and typography to more complex interactive components. As these elements would be consumed in many places, your system has the power to institute real change across your product.

There are many reasons why people might have different experiences with using the web or apps, from temporary to more permanent impairments, so it’s good to assume that not everyone has the same set-up or experience. That might be using a keyboard to navigate, using a screen reader to have content read aloud and like anyone else, we can’t assume anyone using assistive technologies would have the same set-up.


Accessibility at scale in our design system

If you use a method such as Atomic Design to break down the complexity of your layouts into smaller bits, each collection or layer of the system offers us opportunities. 

As much of working with a design system is around bringing teams or specialisms together, considering accessibility from the beginning, or making that part of the success criteria, can make a real impact on your audience(s). Being inclusive through creating accessible products allow for us to reach wider audiences, with as many people as possible able to use and understand what we’re creating. is a great example of building accessibility from the start as it provides the backbone for many complex services for an incredibly diverse audience.

Considering not just how it looks and should work in our design tools, but what conscious considerations are needed to make it more inclusive. How might the design be implemented by developers? There are not just the individual components themselves, but how they play as part of more complex components and a layout as a whole to consider. Their context of use can add challenges which are solvable when working together (cue: “Everything is Awesome” from The Lego Movie).


Setting constraints

Before we even open up your design tool of choice, we can pause to think about the component we need. What is it doing for or communicating to the user? Are there some constraints that we can already apply such as not relying on color alone (as color-blindness could preclude some people from seeing differences in color)? We might start with a few notes, which can be added to your documentation:

  • We have a _____ component to enable the user to _________ (this should give us clarity over what the purpose of what we’re creating is; which handily can also form the start of our documentation)
  • Is there anything we need to be aware of with the wording (microcopy)?
  • If this copy is read aloud by a screen reader does it make sense or should we provide additional context in some way?
  • Is it clear to the user what might happen when they use it?
  • If iconography is used, is there a text equivalent?

With the next component you create, what constraints would you impose on yourself to apply more inclusive design principles?


Accessible design: Starting with a button

So let’s see how we might apply this; a button is often a useful example because they consume some of our basic properties, like colors and typography. They don’t tend to be used on their own and so can be consumed by more complex components. It might have a single visual execution but may need to be made using a <button>, <input> or <a> tag in code. With each method, we want to make sure people can use it and that it works as part of a whole.

The intent from a design perspective may be that this is a call to action of some kind. That may mean different things, from navigating to another page to triggering some kind of behaviour like submitting a form. Regardless, we can agree that this object should be called a Button component. In isolation, trying to make it as inclusive as we can, we should look at things like

  • Readability: Is the font size sufficient for our audience to understand the text on the button? Is the text scalable so that users that have changed their OS or browser settings to show text larger still have a good experience?
  • Color contrast: Is the text's color different enough from the background color so the text can be clearly read? (See Color accessibility workflows by Geri Coady and MDN’s overview of the WCAG guidelines on color contrast)
  • Hit area: We can assume in a responsive layout that any device could have touch capabilities, but making clickable objects a reasonable size can also help with some types of assistive technologies. Assuming any devices could have touch capabilities is probably a good route to take, ensuring that we take on board guidelines around target areas such as WCAG, Apple and Android.
  • States: There’s typically more than just a button (or link depending on the execution of our Button component design) default state to consider. What happens if someone hovers over it with a mouse or focuses on it with their keyboard? Is there a state you want to cater for if it’s active or already interacted with by the user? Each state needs to consider our first two points around readability and color contrast, which can be easily overlooked as we think about its visual presentation. You could consider loading/unloading, hover, focus, active, visited and inactive states for a component such as this.
  • Action: In the case where the user’s interaction triggers some behavior, like opening a modal, submitting a form, or navigating a carousel, we need to understand that this simple component may have many use cases in the system and leave it open to various use cases. That might mean a disabled or unusable state of the component is applicable if an action can’t be completed. In our code, there may need to be ways of triggering the action based on various kinds of user input. JavaScript, for example, has the concept of  ‘event listeners’, which can watch out for a user event like a click or a hover and allow us to react to it.
  • ARIA: most often, using the semantic tags in our code is the best way to go, but ARIA (Accessible Rich Internet Applications) is a collection of HTML attributes that can be used to enhance our components. For our button component, we may have use cases where it expands a section of content or acts as a toggle, so there are attributes that can help us communicate that. 


At the system level

Our button is now pretty good; it’s fundamentally accessible at its core. We’ve considered how we might use it and some of the challenges we might come across in various use cases when used on our website. There may be more complex components that can consume it so we see how well it works in various contexts of use and we may have some automated or manual testing in place and is now available to be used. In some ways, it’s not really complete until it’s used ‘in the wild’ in production code. This is where we get the best learnings - a component like this will be used all over and can teach us a lot about how to improve.

We might decide that while visually it’s a button, the execution might make sense to mirror how it’s output in code, so we may have three components (based on our earlier example of it potentially being coded as a <button>, <input> or <a> tag) that share the same appearance… or we might not. There may be times when the tabindex needs to be changed; while this is an HTML attribute, it’s worth considering it in design - is there a change required here too? Wherever we end up, we need to be aware that our users will form a mental model of how our site works and how to interact with it, so we need to understand the rationale behind our choices and be consistent with how we implement them. Another great instance where documentation comes into its own (*cough* zeroheight *cough*)!


Making changes

If we fast-forward, this simple Button component might now be used in many places across your system as part of other components. We absolutely can make changes and should whenever it makes sense to, but we add an element of risk with such a comprehensive change. 

In tools like Figma, we now have functionality like auto-layout that can cope with a change in dimensions we might introduce into our library of components. We can change properties like the color, typography and possible padding without much of an issue, but if we need to make a more significant change, we may have a ‘breaking change’ that needs its impact checked before made available to everyone. The same would be needed in code. While that’s a workflow that may be different for many of us, documenting our decisions around how we made this button accessible and the use cases we’ve learned helps preserve all the knowledge now embedded in our simple Button component. That leaves a legacy for other designers and developers to keep those good practices and not experience any regression. Change is good but across our design tools and our code implementation, we need to understand the impact of these changes and not lose the gains we make around accessibility.


Testing to keep our work accessible

There are tools we can use to ensure we're doing things accessibly. When we reach the visual design and UX stage in our design tool of choice, we can look to use some plug-ins to look at some aspects as we work. Here are some examples for Figma:

  • Color Blind does a great job of showing you how various types of color blindness might look
  • Low Vision roughly simulates differences people might experience with their sight
  • aXe for Designers is in its early stages at the time of writing but looks to be really interesting
  • The Stark suite of tools has some interesting bits of functionality around focus order and landmarks thought a lot of the functionality appears to be in the paid ‘pro mode’
  • Hemingway helps us to check over the text we’re using

Between the constraints we defined for ourselves and being aware of what we can check in our design tools, we look to our code. We’ve talked about some of the mark-up we might write and some of the challenges we might come across but there are tests and checks we can bring in as we’re writing or when our code builds. As with many aspects of design systems, we get the best results here when we bring design and development together to collaborate.

My editor of choice at the moment happens to be VSCode so there are extensions you can add to help while you work:

Marcy Sutton has a slide deck that goes into some detail about the kinds of testing you can write for your components that may catch most issues, which gives us confidence in not regressing with the accessibility gains that we make.

Most of us would have some kind of build process whether that’s just on your local environment or on a CI/CD server somewhere. There are things we can do at this stage too, which we can choose to either give us feedback or fail builds on:

  • Using Lighthouse in your build processes. While Lighthouse can test for many things through its command-line toolset, we can specify we’d like it to check for accessibility and define how it’s configured.
  • Or take a look at pA11y, which has a number of tools from those you might run in your Terminal as you’re working to running on your CI system to a web service or dashboard.

The human touch

While we have all of these tools and plugins that can help us to incorporate accessibility into all stages of design and development, there’s no substitute for manual testing or trying out assistive technologies such as screen readers for yourself. Guidelines (such as WCAG) and tests will get you a good way to an accessibility design system and so accessible output, but when it’s all put together can everyone complete their tasks easily? We always need to keep it at the forefront of our minds that despite systems and automation, we’re people making things for other people; as colleagues within your organisation and the audience(s) for your website or app. There’s no substitute for listening and getting close to our users’ experiences as we can!

Want to talk about design system accessibility?

How do you incorporate accessibility into your design system workflows? Is there something you do that we’ve not captured here? We love this stuff so join us and other design systems folks in zheroes (zeroheight Slack community) or on Twitter.

Was this article helpful?