Should a library be an easy mode for Accessibility? Yes. No. Maybe.
This is particularly apparent with a component like a progress bar.
A progress bar can be used as a loading indicator, an upload indicator, a background process monitor and so on. While a component library doesn’t know how the indicator is being used, there are a number of values that can be used to help screen readers understand what is going on.
These include role
, aria-valuemin
, aria-valuemax
, and aria-valuenow
(unless it is indeterminate) as well aria-valuetext
. Those values are common among all uses and can be inferred from values passed to the component props.
It also needs some way to help a screen reader to express what this random bar is for. This is where a label
, aria-label
, or title
comes into play. Should a component library make a decision to always require a label
with aria-labelledby
; maybe an aria-label
or even a title
to take control of this situation and offer an easy path toward meeting accessibility guidelines?
I am going to throw out title
because it can create a native tooltip, so let’s start at label
instead. This could be great choice since it offers affordance for screen readers as well shows the label
on the screen. When the design hides (.visually-hidden) the label due to space, etc., this can lead to degraded experience when not using a screen reader, but hopefully other design cues can offer clues to it’s role visually.
How about requiring an aria-label
? Requiring this one can get tricky fast. It, like a label
, offers affordance when using a screen reader, but, unlike a label
, neglects offering visual affordance. What would a component library do if a label
was shown in the design? Since a label
/aria-labelledby
and an aria-label
should not be used at the same time, the component will need to be aware that a label
has been provided and remove the aria-label
.
Whether you are designing systems or individual modules, never forget to use the simplest thing that can possibly work.
— Robert C. Martin
What would happen if we didn’t require an aria-label, but instead we set a default value. I’m thinking aria-label=’progressbar’
, problem solved. Not really. This might even be worse. Once again the component will need to remove the attribute if a label
is provided and we are now just checking a box without regard for the experience when using a screen reader. Plus, progressbar “progressbar”
is redundant and doesn’t offer any context about what the component is there for, so we are back in the same spot as we started albeit with a box checked.
What would a component library do without a pattern language? A design system is comprised of a number of parts including typography, colors, components and, importantly, pattern language. This is where I feel that something like accessibility guidelines and patterns should exist. A pattern can be created to show how to use a component and a label
or aria-label
to achieve the best screen reader experience possible. When to create a label
and use aria-labelledby
vs when to provide an aria-label
based on the design and the user experience. Control what we can through the component and guide the correct usage through patterns.
Should a component library throw errors when accessibility guidelines aren’t followed? I don’t think so. Leave it to the tools that are made to help with this. The W3C provides a list of tools that can used to help check that an implementation meets accessibility standards. Start there then manually test, visually and with screen readers, to validate that the experience is the best it can be for all users of the product.
References:
- https://www.w3.org/WAI/ER/tools/
- https://carbondesignsystem.com/components/progress-bar/usage/
- https://gomakethings.com/revisting-aria-label-versus-a-visually-hidden-class/
- https://www.magentaa11y.com/checklist-web/progress/
- https://w3c.github.io/aria/#progressbar
- https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/progressbar_role