Enforcing Accessibility Best Practices with Automatically-Generated IDs
One of the best things about design systems is you can create components that have design, development, accessibility, responsive, performance, etc best practices baked right into them. By taking care of the boring stuff, users of the design system don’t have to think about (or at least think as hard about) certain things, freeing them up to focus on more pressing tasks.
You likely know that form fields must have an accompanying label, which is often handled by providing an id
attribute to the label, like so:
This creates a relationship between the label
and the input
, resulting in an accessible experience for users using assistive technologies and a better UI experience since now clicking/tapping the label focuses users into the input. Pretty cool!
This is relatively easy to wrap your head around, but it can get tricky fast when you want to provide additional instructions for a form field, such as using the aria-describedby
attribute to create a relationship between the field and helper text.
Now you have two id
attributes to juggle, and when you play this out across a whole bunch of form fields it can get hard to keep track of everything. As a result, maybe developers start dropping the ball and omit the aria-describedby
attribute or even the main field id
. That’s a problem!
How can design systems help with this? One way is to enforce this things using mechanisms like PropTypes, but it would be even better if the system could take care of this itself.
One little trick that I picked up from browsing the Lightning Design System React library was automatically generating id
s using a little library called shortid, which generates a unique gobbledygook string like qPbdivDEiH
. We can still give developers to define their own id
and aria-describedby
attributes, but if they fail to enter them those ids are automatically generated. What this looks like in React-land is something like this:
What’s going on is we’re generating two new id
s using the shortid
library, but also defining an id
prop. Looking at the code id={id || this.generateId}
means “use the user-provided id
prop, but if the user doesn’t provide one use the generated shortid
.
Using the component now looks something like this:
Will result in:
But if the user doesn’t declare any ids like so:
The result looks like this:
Because the user didn’t enter specific values, the component uses the generated shortid
s. While it looks a little uglier, it still provides the same accessible experience.
What does all this mean?
What this means is that it’s impossible for users of the design system to omit an important attribute and accidentally create an inaccessible experience. This technique works well for any component that needs to create an association between two or more ids, like:
- Accordions
- Tabs
- Radio group fields
- Checkbox group fields
- A bunch of other stuff
Of course, this doesn’t solve all our accessibility issues, but it at least takes care of something important that can feel a bit tedious.
Are you using techniques like this in your design system? Any gotchas? Would love to hear from you.
from Brad Frost https://ift.tt/2Yst6eO
Comments
Post a Comment