One way to prevent avoidable issues is to approach building for accessibility the way you build a web or native app from the ground up, in a stack of technologies, where each one has its role to play. Just like you carefully consider what backend language (if any), framework language, and additional libraries you might want to use for your app before you start building, the same should be done for accessibility.
In the coming months, we’ll be discussing and deconstructing what you know about accessibility by rethinking our most basic assumptions about it, from where it should begin to who it includes, and where it fits in a larger inclusivity strategy for your organization. We’ll share case studies, tutorials, and things we’ve learned through usability testing with real users to help you refresh your thinking about accessibility and what it really means for designing, building, and testing your products and services. Stay tuned!
A development stack for accessibility
When first starting out, it can be tempting to “add” accessibility after front-end development work is done. However, just like any development process that tacks additional functionality onto a feature that’s perceived as being done, this approach can quickly result in accessibility solutions that are over-engineered, fragile, or too focused on a single user group to the exclusion of others.
It’s frustrating and stressful to try to make a feature accessible after the fact. That shopping cart preview that’s viewed on mouse hover looks great, but it needs to be keyboard accessible, too. The seatpicker widget is arrayed in a responsive grid, but the grid isn’t a table, and the individual buttons don’t have labels available to assistive technology users or speech-to-text users. And that slick drag-and-drop interaction to organize your custom Kanban board, which is all built with <div> elements because that’s what the framework used? That’s going to be a pain to rebuild.
One way to prevent these types of issues is to approach building for accessibility the way you build a web or native app from the ground up, in a stack of technologies, where each one has its role to play. Just like you carefully consider what backend language (if any), framework language, and additional libraries you might want to use for your app before you start building, the same should be done for accessibility.
Seeing the big picture
Solving for inclusivity
There are a few main questions to ask before you begin deciding what level of the stack to use:
- What content, context, and functionality does the user need to use and understand the feature?
- How is this information conveyed to all users in code?
- What is the lowest-stack solution for helping users reach that goal?
The first two steps should seem familiar, since they represent the basis for good UX and development design practice. But that last question might seem at odds with the previous ones, so let’s break it down.
The accessibility stack
To start thinking about how to scale your web app, it can be helpful to group development problems into four levels of tools, where each level is used to solve a problem that the level before it can’t on its own. If you’ve done accessibility work in the past, you can probably guess what at least most of the stack is:
- HTML gives the structure and order of content.
- CSS provides presentation.
- ARIA creates additional “rich interactions” for assistive technology users.
While these four seemingly simple parts conjure a nicely balanced layer cake, the truth is that some problems will be solved with only one part of the stack, maybe two, maybe three. Really, the shape is less of a cake and more of a mountain or pyramid, where the lower levels provide the most robust support to the most users. Every feature (and user) needs HTML, and from there, each layer serves an important, but less substantial, purpose, until the top of the mountain finishes off the feature stack with support for the smallest user group.
When done right, HTML should:
- Provide the order that focusable content receives tab focus for interactive elements on the page (for users who rely on the keyboard or a similar input device), as well as the order it’s accessed by with assistive technology users.
- Convey the default text alternative or decorative nature of an image via the alt attribute for assistive technology users and those who turn off images.
- Create native interactive features like links, buttons, and form fields, along with programmatically available text and labels, that provide support for all users. Native features that always look and behave normally give clear context for assistive technology users, users with cognitive disabilities, and users targeting elements on the screen with speech-to-text software.
HTML and CSS
Use CSS to enhance or complement the content provided by HTML, or hide content that users aren’t meant to have access to yet. Need to provide extra text for assistive technology users only? Do it with CSS. (Or consider allowing it to be visible in native HTML for all users!)
When implemented with accessibility in mind, CSS:
- Hides or shows content for all users, or shows content to assistive technology only, which can be hidden in HTML with CSS.
- Adjusts the layout based on viewport or device size. Keep in mind that users with low vision may trigger layouts designed for smaller screens on larger ones by increasing the font size or using OS-native or third party magnification tools. Remember, too, that floating content right can cause a mismatch between the visual, “correct” order of content and the order that assistive technology users find it.
- Provides high contrast-friendly styles to users with low vision who use OS-level or custom color schemes, as well as for users who have issues with color contrast. (Remember to give anything with a background color or image a border, and provide a text alternative for information conveyed with color alone.)
- Allows users, especially those with vision, motor, and cognitive issues, to make dynamic changes easily and intuitively by managing keyboard focus.
- Inserts and removes content in logical places in the DOM to help support logical reading order, focus order, and contextual understanding.
- Changes values for attributes and adds and removes attributes to support accessible content and CSS updates.
- Provides for custom keystrokes or other inputs for complex, non-native features. (Don’t forget to let users know how to use your custom features, if you build them, using HTML and CSS.)
A ship-shape ARIA implementation includes these considerations:
- ARIA is not a cure-all, even for assistive technologies. Just like browsers handle HTML5 elements differently, assistive technologies respond differently to ARIA functionality. Using ARIA sparingly and doing your research to see which features are best supported will help provide progressive support where it’s needed.
- It’s implemented for elements that it’s specified for, and uses valid attribute values. Unlike data attributes, ARIA attributes have names and values specified by W3C guidelines to work correctly between user agents (that is, browsers and assistive technologies).
It’s, of course, possible and sometimes necessary to combine the stacks in a different order (say, HTML and ARIA only), when you’re building your own features from scratch. For example, using aria-hidden is recommended for hiding icon fonts from assistive technologies, since different types of software parse content introduced in CSS differently.
If you do need to skip a layer, just keep in mind that the pyramid requires a wider base than it does a peak, so make native, semantic HTML the foundation for every solution to keep your pyramid stable.
The first step is to get better acquainted with the semantics of the HTML5 specification. You might be surprised what it can do for you all on its own.
Next is to brush up on CSS, and not just emerging CSS4 functionality. Remind yourself about what CSS properties actually do, such as which ones hide content from users and which don’t.
Next, review the ARIA specification, especially the roles, and cast a close eye over the recommendations for using ARIA in HTML. Make sure you’re not trying to do in ARIA what can be done in a lower part of the stack.
And finally, determine whether what you’ve built is actually usable. Don’t be afraid to run your work through its paces with actual users, and to learn from how they actually interact with your code. In the end, the stack is designed to make your work work for them.