Making a site or application accessible can seem so overwhelming that it can completely stall efforts before they begin. But sometimes simple changes can provide the necessary momentum while resulting in significant improvements for users.
So, in the spirit of small things that make a big difference, here's a list of fixes for common accessibility problems.
CSS reset files often suppress default browser focus styles. As a result, developers and designers can forget to style the focused state for UI controls. Without focus styles the user is unable to navigate via keyboard.
Unplug the mouse and use the Tab key to move focus through the interactive controls (e.g. links, buttons, form controls, etc.) on the page. Identify the controls that lack a focus style and then update the CSS. Commonly used properties for styling focus are outline, box-shadow and background-color as they don't impact layout. For example:
outline: dotted 1px #000;
Note: IE6 doesn't support the :focus pseudo class. It does support :active, but only on anchor elements. IE 6 will render a default focus outline around all focusable elements as long as it hasn't been disabled via the hidefocus attribute. For IE 6 best to just confirm the default browser focus is visible and consider custom focus styles a form of Progressive Enhancement.
Use the button role to make link buttons into, er… buttons
Using the button role
For link buttons, simply add the ARIA button role.
<a role="button" tabindex="0">Click Me</a>
For buttons created using another element (like a <span>), add the button role. Set the tabindex to 0 to place the button into the default tab flow.
Another solution is to simply just use a <button> for buttons.
This bookmarklet can help identify link buttons that could benefit from an ARIA role of button:
Show Link Buttons
Label UI Controls
UI controls sometimes go unlabeled. Screen readers announce a control's label when it receives focus, so without text labels users of screen readers are unaware of a control's purpose or function. Text labels also focus their associated form control when clicked, a nice usability affordance for smaller controls like checkboxes and radio buttons.
The following is a comprehensive list of labeling techniques for UI controls.
Text placed between the opening and closing tags. If the design doesn't require the text label be visible, hide it in an accessible way using CSS.
Tried and true method of labeling form controls. If the design doesn't require the text label be visible, hide it in an accessible way using CSS.
Note:Implicit labeling is broken in IE 6. In the following example clicking the label text won't focus the associated form control.
Use title to label frames. Might also be a good last resort if you are constrained for space (like a form element in a table cell). Otherwise, title isn't a good choice as a labeling technique.
Used to label an image. There's no shortage of guidelines for writing good alt text, but here's some things to keep in mind:
- Use an empty string for decorative images, or if there's no text available.
- If the image contains text, replicate it in the alt attribute.
- Otherwise, try to be succinct.
- Under no circumstances omit the alt attribute. An empty string is better than nothing.
Specifies the text label inline, but isn't visually rendered. Handy when there's no space for label on screen and title is already used to supply an instructional tooltip for sighted users. For example a checkbox in a table cell:
Note:aria-label is not currently supported in Internet Explorer (9).
Specifies the id(s) of the element(s) whose text content labels the control. Useful when the desired label text is already present in another element in the DOM. Saves the creation of another <label> element.
Specifies the id(s) of the element(s) whose text provides a description supplemental to the label. For example: an error message associated with a form field that has invalid user input.
This bookmarklet can help identify UI controls without labels:
Add the required attribute to required fields
Required fields are often indicated using visual style, or an asterisk adjacent to the field's label. As these solutions rely either entirely, or mostly on visual style they are completely inaccessible to users who can't see the screen.
HTML5 adds a required attribute to form controls. To supplement lack of browser support for required, use it together with aria-required. When a required field is focused, the screen reader will announce that it is required. Even better, it doesn't require localization because the required message is localized by the screen reader.
<input type="text" name="first-name" id="first-name" required aria-required="true">
Indicate invalid input using aria-invalid
Invalid user input leaves users seeing red. Unable to see the screen, users of screen readers can struggle to find the fields with errors.
Indicate invalid user input using aria-invalid. Use aria-describedby to associate an error message with a form field.
<input type="text" name="first-name" id="first-name" required aria-required="true" aria-invalid="true" aria-describedby="err-msg">
<p id="err-msg">Cannot be blank.</p>
Remove duplicate links, improve tab flow
Keyboard users navigate between interactive elements via the Tab key. Every anchor element creates a tab stop, so redundant links within a module can create an inefficient overall tab flow, making navigating with the Tab key a real drag for keyboard users.
Improving tab flow
Use tabindex=-1 to improve tab flow
Setting tabindex to -1 removes an element from the tab flow, while keeping it clickable for users of the mouse. This can be used to significantly improve the tab flow of a page.
Consider the following content module: The headline, image, and "More" text are all wrapped in individual links, all of which share the same URL.
This content module has three tab stops. Reduce it to one by setting the tabindex to -1 for the links wrapping the image and "more" text. This change makes a significant improvement to the tab flow when there are multiple instances of this module on a page. In this example, each section has just one tab stop (the heading) instead of three.
Use a single link
If a module contains two adjacent pieces of content and both should be linked to the same URL, wrap both inside a single link.
Consider the following example, where headlines and videos are paired together but the video and text labels are wrapped in separate links. Duplicate links are outlined in red.
Placing the video and text inside one anchor would improve the tab flow of this section. And don't forget, HTML5 enables anchor elements to contain block-level elements, making this approach valid code.
Add a description to make dupe link labels more accessible
Pages often contain many instances of links with the same label. Consider, "read more" links that follow truncated content or excerpts. Without unique labels, users of screen readers can have trouble distinguishing one link from another.
Adding a description to a link
This content module has six links with the label "More".
This screencast illustrates the user experience for browsing the links in this module using a screen reader
Use aria-describedby to give each "More" link a unique description. In this example, aria-describedby is set to the id of the other link in the module that contains a meaningful description for the "More" link.
<a id="link-1" href="http://www.viator.com/Orlando/d663-ttd">Orlando tours & things to do</a>
<div>provided by Viator guides</div>
<div>Book Orlando tours, things to do, and day trips from Viator.com, including ...
<a aria-describedby="link-1" href="http://www.viator.com/Orlando/d663-ttd">More</a>
This screencast illustrates how the description for each "More" link is announce to the user by the screen reader.
This bookmarklet can help identify links with duplicate labels:
Show Duplicate Link Labels
Use the presentation role to hide iframes in plain sight
Iframes are sometimes used for purposes other than serving content (e.g. shims, async requests, etc.). These iframes can be problematic for users of screen readers in that they both add an extra tab stop into the page, and can mislead users into thinking they contain content.
Using the presentation role
Apply the ARIA presentation role to hide the iframe from screen readers. Set tabindex to -1 to remove the iframe from the tab flow.
Label iframes with a title
Iframes are used to sandbox content or functionality (e.g. Like Button, Tweet Button, etc.), but frequently lack a title. This leaves users of screen readers unaware of the iframe's purpose. Worse, the user may have to listen as the screen reader announces a long URL specified by the iframe's src.
Here's a simple example illustrating how to use title to make the Facebook Like button more accessible.