Craft 5.x
In 5.9.0, we improved the accessibility of user permission lists and GraphQL schema component lists. Previously, “Select All” buttons to select all checkboxes in the list were only accessible via pointer devices. They have been updated to use semantic buttons and provide additional descriptive information via aria-describedby.
In 5.9.18, we fixed a bug that prevented keyboard focus from returning to the modal trigger after closing certain modals, like the Passkey Setup modal.
Craft 6
In our Craft 6 announcement post, we announced that Craft 6 will feature a new UI. Some of the key considerations we’ve been focused on include:
- Building a design system that is centered around — and clearly explains — accessibility considerations
- Expanding our testing coverage to prevent accessibility regressions
In all, we’re still deep in the weeds at this stage of the redesign, but we have a solid grasp of the problems we’re trying to solve and a clear plan for getting us there.
Here are some of the things we’re focused on right now.
Starting with accessible components
One decision we made during the UI redesign was to leverage existing component libraries (or parts thereof) as much as possible. There are many component libraries, but we wanted to make sure we focused on one that clearly prioritizes accessibility.
Some of the questions we asked ourselves during the research phase were:
- Can these components be used out-of-the-box? If not, can we extend them to suit our needs?
- How solid is their documentation, accessibility-related and otherwise?
- How responsive are the maintainers to accessibility issues?
Pretty quickly, we narrowed it down to using Lion web components as the foundation of our design system for the following reasons:
- Accessibility is a core concern, and every part of Lion is built with accessibility in mind.
- The components are white label, so only functional styles are provided out-of-the-box. Because we don’t have to override existing styles, we can theme everything to work inside the control panel.
There may be instances when we need to pull in components from other libraries—or roll our own—to fill gaps. But choosing a solid foundation gives us a great starting point.
Auditing from the ground up
In our Craft 6 announcement post, we mentioned that each component will be tested against WCAG 2.2 AA standards. While it’s true that WCAG conformance can only be assessed at the page level rather than the component level, we’ve found it helpful to audit components in isolation before moving on to full-page auditing.
For every major version accessibility audit since Craft 4, we've tracked the audit status of every component in our representative sample.
While the redesign is in progress, we’re using the same tracking method to ensure every component is thoroughly assessed for accessibility.
Building out our design system
One of the benefits of having a design system is that it allows us to thoroughly document our components, explain their properties, and outline their accessibility implications.
Take the example of a badge indicator. You might see this in the Craft CMS control panel when there are notifications or alerts on a page linked from the global navigation, or in the “What’s New” disclosure menu in the top bar when there are unread messages.
An example of a badge indicator in the context of the global navigation.
Some common accessibility issues we’ve seen with things like badges in the past are:
- The use of color to convey different types of meaning
- A lack of alternative text, so assistive technology users aren’t alerted to the presence of the badge
- If there’s an implied context, that it’s also communicated to assistive technology
To prevent developers from using different badge colors to mean different things, we are adopting only a few color options that work for both light and dark backgrounds.
Next, we wanted to ensure we’re providing properties that might be needed to make our badge accessible to assistive technologies. If the badge contributes to the accessible name or description of a link, we want to ensure it has alternative text. Adding an altText property to our component helps us accomplish just that:
Passing altText to the badge component gives the badge indicator an image role and alternative text.
And what about numbered badges? A numbered badge can have a different meaning depending on whether it’s layered on top of a “Shopping Cart” button or a “Utilities” link. In the first example, it might indicate “5 items in cart,” whereas in the latter, it might mean “5 notifications.”
The Numbered Badge story explains the component props relevant to this use case, including those for the number itself and visually-hidden text.
This is just one of many existing UI elements we’ve been componentizing for our design system, and we’re excited to finally document all these accessibility considerations in one place.
Preventing violations
Preventing regressions with automated testing
Storybook’s a11y addon provides a tool for running automated accessibility tests on our components. With the addon configured, our Storybook includes an Accessibility tab that highlights any axe-core violations, passes, or inconclusive results.
For example, any color updates that result in text falling under the minimum contrast ratio will trigger warnings in the Accessibility tab:
Storybook’s interaction tests also enable us to run functional component tests. So in addition to automated tests, we can layer in some things that can only be verified via manual testing, like:
- Making sure components have appropriate roles, accessible names, etc.
- Verifying keyboard focus is managed appropriately; for example, that keyboard focus moves back to the trigger element when closing a modal.
And once the test runner is configured, we can run the entire test suite from the terminal or in CI. In combination, these testing features make it difficult to introduce regressions without sounding the alarm bells.
UI feedback during development
We’re using Lion as a base for building out our Button component, but we’re also experimenting with adding functionality to make accessibility violations more visible.
For example, around 7% of all issues identified in our first comprehensive audit were related to UI elements lacking accessible names. And more than a handful of those issues were specifically due to buttons lacking accessible names.
One thing we're experimenting with in extending the base component is providing visual feedback in the control panel when a button lacks an accessible name. In a recent PR, we customized our button component to display a visual error when a button lacks an accessible name.
Buttons without accessible names are visually indicated with a warning outline.
This may be a feature we only end up using when devMode is turned on, but it’s a benefit because it makes it easy to spot violations quickly during development, before even running tests.
Future work
This is only a fraction of the work we’re doing to make Craft CMS more accessible and usable for everyone, and to improve the experience for plugin developers and anyone else extending Craft.
While there’s a lot of work ahead, we have a wealth of data and insight gathered from our years of ongoing accessibility work to guide us. We look forward to hearing any suggestions or feedback along the way!