Accessibility 101 for web GUI developers
If you’re a web developer who creates graphical user interfaces (GUI) for your applications, then you’re probably familiar with accessibility but possibly daunted by all it entails.
Are you afraid that implementing accessibility into your GUI will require you to read long guidelines, inflate your HTML code with countless additional attributes, make your GUI look ugly — and cost you too much time and money? Well, don’t worry. This article is for you.
In this article, I break down accessibility into a few easy-to-understand core principles and show you concrete guidance on how you can design your new GUI for accessibility from the beginning. While this article doesn’t offer comprehensive guidelines that solve all your accessibility problems, follow these simple principles to avoid the most common mistakes that make GUIs inaccessible.
Four core principles of accessibility
Accessible user interfaces follow these four basic principles:
- Perceivable information and user interface: Users with disabilities can view and understand all the content on your site.
- Operable user interface and navigation: Users with disabilities are able to navigate your GUI and use all the necessary functions.
- Understandable information and user interface: All information is presented in a clearly structured and predictable way and provides clear guidance and help for correcting mistakes.
- Robust content and reliable interpretation: Your GUI needs to be compatible with current and future tools (for example, different browsers, assistive technologies, and other user agents). Because this is a very technical requirement, we will not focus on this principle in this article.
Now that you know the four main principles, let’s look at some tips for creating accessible GUIs. While these don’t align 1:1 with the principles above, the most important thing is that whatever you add to your GUI, check that it does comply with at least the first 3 principles!
Disclaimer: Making a GUI accessible for blind persons (who navigate your GUI with a screen reader) is a complex task which requires measures that go far beyond what I discuss in this article. Instead, I focus mainly on users with limited vision, mobility, and physical impairments. However, it’s important to design your GUI also for “screen readability” from the start in order to be future-proof.
Essential DOs and DON’Ts for accessible GUIs
Mandatory prerequisite: Use a GUI framework
First and foremost, don’t code your site in plain HTML. There are numerous frameworks and widget libraries out there. The input elements built into HTML are not always accessible by design. Frameworks should provide you with useful and accessible widgets like boolean-buttons and swap-selects (see below).
When choosing a framework, check these 3 requirements:
- Widgets are styleable by CSS
- Widgets are also useable only by keyboard
- Generated HTML code contains ARIA meta elements (see below).
Here is a small list of GUI frameworks which support accessiblity:
Also check out this article for a more detailed evaluation of accessible frameworks.
Colors and shapes
Use high contrast for foreground and background colors
Imagine viewing your site on a really bad projector in a room with too much light coming from the window. That fancy light blue icon on dark blue background — you can hardly see it anymore, right? If you change the icon’s color to white, everything is fine. Why? Because white has a much higher contrast to dark blue than light blue. High contrast is essential for people with limited vision (remember the first principle: accessible UIs have perceivable information).
Right now, I could show you some fancy numbers which describe contrast ratios with respect to different text sizes — but you can’t use that in a practical way. Instead, just follow these rules:
- Keep the “bad projector analogy” in mind when choosing colors for elements.
- Choose either a very dark or a very bright background. On a dark background, use a very light font and vice versa.
- After you have chosen your colors, double-check your foreground/background contrast with a contrast checker tool.
Oh, and don’t use color gradients. They are troublesome for accessibility and look outdated anyway.
Avoid color coding elements (and if you do, assign a corresponding shape)
So, you’ve designed a status icon that is a nice little ball. When the ball is green, everything is fine. If it’s red, you’re in trouble. Nice work! But wait — what about people with red–green color blindness? They can’t tell if they are in trouble or not.
There is generally nothing wrong with color-coding elements. For the majority of users, this color coding helps users understand the GUI more quickly. However, color should not be the only distinguishing factor. Either provide a supplementary text or assign a corresponding shape to each color. In the above example, the icon for the red status could be an exclamation mark instead of a ball.
Note: The user will need to be able to distinguish the different meanings of an element simply by looking at it. An additional tooltip is not enough because it requires the user to navigate to the element each time in order to see its meaning.
By the way: This also applies to links! Links should be clearly identifiable by users with limited vision. The best way to achieve this is to use bold or text (or both). You could also use a link color which has enough contrast to the plain text and to the background, but this is rather hard to do.
Don’t use bitmap images
Apart from bitmaps looking pretty 2010-ish, there are some real drawbacks for accessibility, including:
- Bitmaps have a fixed size and produce aliasing artifacts when scaled.
- Bitmaps have fixed colors and often contain gradients which makes it harder to integrate them into their context while preserving the right contrast.
- They are big, which slows down your site. They need to be cached which clutters up a device. This isn’t an accessibility issue, but just another reason not to use them!
Instead, use vector-based images with only one color.
These are the benefits:
- They are freely scalable. Users with limited vision will probably use the browser’s zoom feature, so your images and icons will still look good in higher zoom levels.
- They can have any color, so you can easily choose the one with the proper contrast. You can also use the same icon in different contexts (or change the icon’s color when highlighting).
- Some users use the operating system’s “high contrast mode” (that mode that turns everything on your screen into 80’s style black/white/neon colors). This mode helps users with limited vision to better see what’s on their screen. However, bitmap images don’t change colors in high contrast mode — vector images do.
And of course, each and every image on your site has an “alt” attribute with a description. Right? Right.
Input mask structure
Use clearly structured vertical input forms
In former times, screen pixels seemed to be a valuable resource. Every spot on the screen was often crammed with input elements in no particular order. In order to be operable, understandable and predictable (and screen readable), use clearly structured vertical input forms, in which all fields are displayed in vertical order, underneath one another.
- Don’t use multiple colums in an input form. Each input field should have its own dedicated row.
- Provide clear visual connections between labels and fields. Labels shall be right aligned!
- Show validation errors and hints directly next to the corresponding fields.
- Don’t show too many fields in an input mask. Consider using different sections or a tabset.
Don’t use inline table editing
If your GUI shows tables with data that is editable, don’t ever use inline table editing (where a single row suddenly turns into a row of input elements, whereas all other rows remain plain text). The main reasons for not doing this:
- The user wants to interact with only this one record. Displaying all the other records only takes up screen real estate and distracts the user.
- The input elements don’t have a clearly assigned label except for the column header, which may be 10 rows above the editable field.
- There is no space to display additional elements like the help icon or the mandatory icon.
- There is no space to display field-related error messages when validation fails.
- Assistive technologies, especially screen readers, can’t easily interpret that kind of GUI structure. The odds are small that information will be presented to a blind user so she can clearly understand what the system wants.
Instead, when the user wants to edit a record, show a vertical input form that follows the rules described above. This keeps your GUI consistent and understandable to the user.
You have 2 options:
- If the record only has a handful of fields, show a modal dialog (“overlay”). The dialog hides a part of the table temporarily, but the user does not move away from the page. That way, the context does not change and the GUI becomes more predictable.
- If the record contains more fields than the table’s columns, you probably would have changed to a dedicated vertical input form anyway, right? But remember: That change requires the user to return to the table after making changes to the record. However, her context (like filtering, sorting, or paging) may be lost. So don’t change to a whole different page if not necessary — use dialogs when appropriate.
Avoid checkboxes for single boolean fields
According to proper GUI best practices (and screen readability), a checkbox must have a label on the right side showing its meaning. On the other hand, vertical input forms are often presented with the following layout, showing the field label left of the input element:
This would result in the following layout, where the label of the checkbox is on the wrong side:
Fortunately, there are some alternate widgets that are suitable for a single boolean option, one being a “Boolean-button”:
On mobile devices, toggle switches are often used.
Note: This rule applies to checkboxes as an input element. You can still use “checkbox-like” read-only icons to show the value of a boolean flag, for example in a column of a table. However, as soon as the user has to change the boolean value, use one of the widgets described above.
Use the correct widget for different select field types
Select fields are tricky. Almost every web site gets this wrong in one way or another. I won’t get into the details of things NOT to do since there are too many, but allow me to stress one point: Don’t ever use those old-fashioned “ctrl-click-multi-select-listboxes”! They drive everyone crazy, but especially users with disabilities who have to use a keyboard.
Instead, here is an attempt for a comprehensive matrix of accessible widgets to use for select fields:
For those of you who are not sure what a Swap-select is – it’s a widget with two lists: One containing all options available for selection, one containing all currently selected options. In between there are buttons for moving items from one list to the other. What makes this widget accessible is that keyboard users and mouse users alike can move items one by one by marking an entry in the list and then pushing the desired button.
A “filter” for a dropdown-list or a swap-select is a “find-as-you-type” textfield shown above the list of possible entries. This is a handy feature not only for users with disablities, because the user can reduce the number of options very easily.
Keyboard navigation is a huge part of accessibility. Using a mouse may be easy for you, but it is a rather complex motion which some users are not capable of. These users navigate your site only by pushing buttons on a keyboard (which is a much simpler motion). Additionally, blind users cannot use a mouse.
Hopefully you’ve seen that keyboard navigation is, in fact, a rather effective — and fun — way to use a GUI. Strangely enough, many users still just don’t expect a web GUI to support keyboard navigation. Tip: When developing your GUI, do everything by keyboard by default. If you get it right, it’s fun, effective, and accessible!
Make sure all widgets are accessible by keyboard
Choosing the right GUI framework should ensure this is done (see the “prerequisite” above). All your input elements, including the complex widgets like swap-selects, should be usable by a keyboard.
Make keyboard focus clearly visible
Keyboard users should be able to step through all the elements on your site using the TAB key. Apart from choosing a logical order of the tabstops, you have to make sure the user clearly sees where the current focus is. Remember the users with limited vision! The surest way to highlight the focus is to draw a separate frame around the item, using a color with proper contrast to the background. Don’t just give the item itself a different color — mind the color-blind users!
Every icon should have a tabstop with a tooltip
It is common for GUIs to contain many small icons. However, sometimes the meaning of each icon may not be obvious at first sight. You might think this isn’t a problem since you assigned an “alt” attribute! Your browser displays the text of the “alt” attribute on mouseover and screen readers can easily interpret the “alt” attribute! So, who’s still missing? The poor keyboard users. They have no way to access the content of your “alt” attribute.
Tip: Don’t use the standard browser-based tooltip. Use the CSS-styleable tooltip from your GUI framework. You can match its appearance to your design and adjust the contrast as needed. It usually shows up with no latency.
Use global keyboard shortcuts (“commands”) to directly access certain elements and functions
So you have crammed your GUI with tabstops. Each button, each icon, each and every element is accessible just by hitting the TAB key often enough. Unfortunately, that can result in numerous tabs. To reach that “New” button on the bottom right corner of the page, the user has to hit the TAB key two dozen times. Every time. For blind users this is even worse: On each tabstop, they have to listen what the screenreader says in order to know where the focus is at the moment. Pretty unnerving, right?
Global shortcuts, or commands, address this problem. Remember that old text editor vi? When you hit the ESC key, vi does not accept user input to the document anymore and enters “command” mode, where you can do “global” things to the document like saving or jumping to the beginning or the end of the document. This principle has been widely adopted for web accessibility.
Whenever the user hits the ESC key on your page, the keyboard focus should go away and your page should be listening to a set of predefined commands. Most importantly for accessibility, you have to define a set of hotkeys that allow the user to directly set the keyboard focus to certain elements of your page. Now each page is different, so I can only give some examples here:
- M: set the focus to the first item in the main menu
- N: set the focus to that “New”-button in the bottom right corner
- F: set the focus to the first input element in the input form
- H: set the focus to the online help icon
Alternatively, you can assign numbers to the different sections on your page, and the user can jump to each section using the corresponding number key.
Apart from that, it is common practise that you include the following commands (if applicable):
- ?: open an overlay dialog showing all the possible global commands
- J: jump to the next element in a list
- K: jump to the previous element in a list
- /: set the keyboard focus to the global search field
When writing your HTML, don’t just focus on how the actual rendered outcome looks. Let’s look at an example. Suppose you are creating a button. You write a
The solution is “Semantic HTML”. HTML5 and WAI-ARIA offer HTML elements and attributes which describe the actual meaning of a particular GUI element. While this alone is a topic for a whole series of articles, let me give you some of the most important rules for semantic HTML:
- Don’t use tables for layout. Use dedicated “structure elements” like
<article>for structuring your page layout.
- Structure your text content using elements like
<p>instead of individually styled
divelements with a plethora of
- Use the
<button>element for… well, buttons.
- Use the
<label>element for assigning text labels to input elements.
- Don’t use empty “pseudo links” to simulate behavior (
<a href='#' onclick='...'). Use dedicated elements instead (for example,
- Use additional WAI-ARIA markup to add semantic markup that built-in HMTL does not provide, for example
tree. However, these ARIA elements and attributes are often already included into the HTML code by the predefined widgets of your GUI framework.
Congratulations, you made it through all the points! You probably knew many of these things already, but I hope you got to understand GUI design from a slightly different perspective. After all, accessibility doesn’t seem to be that big of a deal, right? Well, the famous Pareto principle applies to accessibility, too: If you invest the additional 20% of effort into your GUI by following these rules, it is likely that your GUI is accessible to 80% of users with disabilities.
However, if you plan to (or even have to) make your GUI accessible for the remaining 20% (especially blind users), then you have to invest the remaining 80% of effort. And that means digging into the W3C guidelines, learning everything about ARIA and throughly testing your GUI with a screen reader. But this is a whole different story.