Best Practices
Check it out yo!
This is the list of html structure and design best practices. I leech them from blogs and stuff. I hope I could get as many reference as I can and pour them here.
Please consider the following points
-
Keyboard navigation (disable your mouse)
-
:focus pseudo selector
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:
<style> button:focus { outline: dotted 1px #000; } </style>
-
role="button" attribute
Links are often used to create buttons. When an element is focused, screen readers announce its tag name. That means users of screen readers will perceive link buttons as links. Worse, the value of the link's href may be announced. This can be especially confusing to the user if the href is set to "#" or "javascript:…".
For link buttons, simply add the ARIA button role.
<a role="button" href="#">Click Me</a> <a role="button" href="javascript:callback();">Click Me</a> <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.
<span role="button" tabindex="0">Click Me</span>
Another solution is to simply just use a <button> for buttons.
<button type="button">Click Me</button>
-
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.
This content module has six links with the label "More".
Notes: a blog page with lots of "more" links was here on the original page.
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.
<div class="article"> <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> </div> </div>
-
-
forms
-
label element
Use both label and aria-labelledby for better screen reader coverage.
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.
-
Inner text
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.
-
<label> element; title, alt, aria-label, aria-labelledby, and aria-describedby attribute
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.
<label>First Name <input type="text" name="first-name"></label>
-
title attribute
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.
-
alt attribute
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.
-
aria-label attribute
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:
<input type="checkbox" aria-label="Message 1" title="Click to select this message">
Note:aria-label is not currently supported in Internet Explorer (9).
-
aria-labelledby attribute
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.
-
aria-describedby attribute
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.
-
-
required attribute
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.
<label for="first-name">First</label> <input type="text" name="first-name" id="first-name" required aria-required="true">
-
aria-invalid attribute
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.
<label for="first-name">First</label> <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>
-
Make <input type="radio"> and <input type="checkbox"> more accessible
-
label element.
<label><input type="checkbox" id="checkbox1" value="food"> Food</label>
Wrap form control with small focus inside label whenever possible. This increased clickable zone and required by people with motoric disability.
- Safari doesn't support clicking label unless that input element is child of the label.
- NVDA will read the label twice.
- :hover pseudo class.
-
Make disabled controls more obviously disabled
form *:disabled { cursor: not-allowed; }
See my reset stylesheet for a more efficient selectors.
-
-
iframes
-
role="presentation" 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.
Apply the ARIA presentation role to hide the iframe from screen readers. Set tabindex to -1 to remove the iframe from the tab flow.
<iframe role="presentation" tabindex="-1"></iframe>
-
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.
<iframe title="Like this page on Facebook" src="http://www.facebook.com/plugins/activity.php?site=news.yahoo.com&width=290&height=300&header=false&colorscheme=light&font&border_color=white&recommendations=true" frameborder="0" scrolling="no" style="width:290px;height:300px;"> </iframe>
-
-
Styling
-
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.
-
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.
Notes: a blog post image was here on the original page.
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.
Notes: a row of image gallery and their title was here on the original page.
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.
-
-
roles
-
Landmark roles supported by NVDA
- banner. A region that contains the primary heading or Web site title. Most of the content of a banner is site-oriented, rather than being page-specific. Site-oriented content typically includes things such as the logo of the site sponsor, the main heading for the page, and site-specific search tool. Typically this appears at the top of the page spanning the full width.
- complementary. Any section of the document that supports but is separable from the main content, but is meaningful on its own even when separated from it.
- contentinfo. Meta information which applies to the first immediate ancestor whose role is not presentation. In the context of the page this would apply to a section or the page of which it is the child. For example, footnotes, copyrights, links to privacy statements, etc. would belong here.
- main. Main content in a document. This marks the content that is directly related to or expands upon the central topic of the page.
- navigation. A collection of links suitable for use when navigating the document or related documents.
- search. The search tool of a web document. This is typically a form used to submit search requests about the site or to a more general Internet search service.
Other roles: application a region declared as a web application, as opposed to a web document, form a landmark region that contains a collection of items and objects that, as a whole, combine to create a form.
- tabpanel and tab. Collapsible content, see the link for sample of javascript to implement.
- alert.
aria-*
- aria-live="assertive"
Sources and more things to read
- Focus, label, required, aria-invalid, tab-index, presentation, title.
- Not all aria widget deserves role application. Also about NVDA special behavior regarding application role.
Extra notes, how to use screen reader
- Navigate through landmark role.