Skip to content

alebelcor/effective-a11y

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

Effective a11y

Hands-on Web accessibility.

Table of contents

HTML

It's better to combine adjacent image and text links into a single <a> element.

Provided the <img> element contained in the <a> element would:

  • Have an empty alt attribute when the <a> text would duplicate the information conveyed
  • Have a valid alt attribute value when it would complement the <a> text

The tabindex attribute may be used to alter the tab order when the default is insufficient. For example on forms, or when a search field is the first thing you want users to tab into.

The alt attribute may be used on an <area> element to provide text alternatives on regions of an image map.

All HTML pages, including frames, must have a <title> element in the <head> with a simple phrase defining the purpose of the page.

Use the <abbr> element for any abbreviations, acronyms, and initialisms.

Provide descriptive text as the content of the <a> element.

If the only content of a link is an image, the text alternative for the image is used instead.

When the content of a link contains both text and one or more images, if the text is sufficient to describe the purpose of the link, the images may have an empty text alternative. When the images convey information beyond the purpose of the link, they must also have appropriate alt text.

Provide a way to submit form data by having one of these:

  • <button type="submit">Submit</button>
  • <input type="submit">
  • <input type="image">

Use the title attribute on the <a> element to provide additional text describing the link. It's used to clarify or further describe the purpose of the link.

Information the user should know, before following a link, should be provided in the link text.

To bulletproof the correct handling of bidirectional text in HTML (for legacy or non-conformant browsers) you can add a Unicode control character to indicate the base direction of the surrounding text.

  • &lrm; or &#x200e; for the left-to-right mark
  • &rlm; or &#x200f; for the right-to-left mark

For example, assuming a base language of English (left-to-right), we'll use a phrase in Arabic (right-to-left) mid-sentence:

<p>As the proverb says "<span lang="ar">اصبر تنل‏</span>&lrm;". Do not despair</p>

⚠️ Note: <applet> is obsolete. Use <embed> or <object> instead.

The alt attribute may be used on an <applet> element to label it. Provide text alternatives to it in the body of the element.

For <input type="image">, the alt attribute of the <input> element is used to provide a functional label that indicates the button's function, not the image description.

When using the <img> element, specify a short text alternative with the alt attribute.

When an image contains words that are important to understanding the content, the alt text should include those words.

The text alternative does not necessarily describe the visual characteristics of the image itself but must convey the same meaning as the image.

The <caption> represents the title of its parent <table>. It's a table identifier and acts like a title or heading for the table.

Using it allows screen readers to navigate directly to the caption for a table if one is present.

Provide description of names or terms using <dl>, <dt>, and <dd>. Multiple terms can be associated with a single description, as can a single term with multiple descriptions.

The title attribute can be used to provide additional information about the description list.

Use heading markup to provide semantic code for headings in the content. It will allow assistive technologies to present the heading status of text to a user. A screen reader can recognize the code and announce the text as a heading with its level. Screen readers users are also able to navigate heading markup more quickly to find content of interest.

Use only when data cells are associated with more than one row and/or one column header.

Add a headers attribute to each <td>. Its value should be the id value(s) of the associated header cell(s) (separated by spaces, if multiple).

Example
<table>
  <thead>
    <tr>
      <th id="b" rowspan="2">Budget</th>
      <th id="g" colspan="3">Groceries</th>
      <th id="r" rowspan="2">Remaining</th>
    </tr>
    <tr>
      <th id="v" headers="g">Veggies</th>
      <th id="f" headers="g">Fruit</th>
      <th id="m" headers="g">Meat</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td headers="b">$50</td>
      <td headers="g v">$10</td>
      <td headers="g f">$5</td>
      <td headers="g m">$20</td>
      <td headers="r">$15</td>
    </tr>
  </tbody>
</table>

Use the <label> element to explicitly associate a form control with a label. It's attached to a specific form control though its for attribute, which must be the same as the value of the id attribute of the form control.

Elements that use explicitly associated labels
  • <input type="text">
  • <input type="checkbox">
  • <input type="radio">
  • <input type="file">
  • <input type="password">
  • <textarea>
  • <select>
Elements that do not use <label>
  • <input type="submit">: Use value attribute instead
  • <input type="reset">: Use value attribute instead
  • <input type="hidden">: Use value attribute instead
  • <input type="button">: Use value attribute instead
  • <input type="image">: Use alt attribute instead
  • <button>: Use element content instead

Provide information in a resource designated by the longdesc attribute when a short text alternative does not adequately convey the function or information provided in the image.

The longdesc attribute is a URI. And can be either a reference to a separate resource, or within the same page.

Example
<!-- Long description in a separate resource -->
<img src="graph.jpg" alt="A complex graph" longdesc="graph-description.html">

<!-- Long description within the same page -->
<img src="graph.jpg" alt="A complex graph" longdesc="data.html#graph-description">
...
<div id="graph-description">
  <p>...</p>
</div>

Provide alternative content for the <embed> element in a <noembed> element.

<noembed> is rendered only if the <embed> is not supported. It is a good idea to include it as a child element of <embed>, instead of positioning it anywhere else on the page, so that it functions as a text alternative associated with the <embed> element it describes.

Create lists of related items using list elements appropriate for their purposes.

  • The <ol> element is used when the list is ordered
  • The <ul> element is used when the list is unordered
  • Definition lists (<dl>) are used to group terms with their definitions

Avoid making lists using (visually formatting) markup like *, , and <br>, as that is more difficult to navigate.

Use semantic markup to mark emphasized or special text. It provides structure to the document, and browsers can use it to make it perceivable to the user.

  • <em> to represent stress emphasis of its contents
  • <strong> to represent strong importance, seriousness, or urgency for its contents
  • <blockquote> to represent a section that is quoted from another source
  • <cite> to represent the title of a work (e.g. a book, a song, a film, etc.)
  • <q> to represent some phrasing content quoted from another source
  • <sup> to represent a superscript
  • <sub> to represent a subscript

Use <table>, <tr>, <th>, and <td> to present tabular information

The body of the <object> element can be used to provide a complete text alternative for the object, or may contain additional non-text content with text alternatives.

The <dfn> element is used to indicate the defining instance of the enclosed term. It marks the occurrence of the term where the term is defined.

The dir attribute is a global attribute that specifies the element's text directionality.

Its values can be:

  • ltr to indicate left-to-right text
  • rtl to indicate right-to-left text
  • auto to indicate direction should be determined programmatically

Identify the default language of a document by providing the lang global attribute on the <html> element.

Identify any changes in language on a page by using the lang global attribute. Its values are defined here consisting of a primary code followed by an optional subcode.

For example: en for English, and en-GB for British English.

The <link> element can provide metadata about the position of an HTML page within a set of Web pages or can assist in locating content with a set of Web pages.

The value of its rel attribute represents the relationship between the document containing the hyperlink and the destination resource.

Several values of rel are useful.

For example:

  • next to indicate the next document in the series is the referenced document
  • prev to indicate the previous document in the series is the referenced document

⚠️ Note: rel="glossary" is a valid link type in HTML 4.01. But it's not part of the predefined list in the latest HTML standard.

Use a <link> element with rel="glossary" to provide a mechanism for locating a glossary on a separate page.

Use the <ruby> element to provide information about the pronunciation and meaning of a run of text where meaning is determined by pronunciation.

Example
<p>
  <ruby>
    <rb>Charlize Theron</rb>
    <rp>(</rp>
      <rt>shar-LEEZ THERR-ən</tr>
    <rp>)</rp>
  </ruby>
</p>

The scope attribute may be used to clarify the scope of any cell used as a header. The scope identifies whether the cell is a header for a row, column, or group of rows or columns. The values row, col, rowgroup, and colgroup identify these possible scopes respectively.

For simple tables that have the headers in the first row or column then it is sufficient to simply use the <th> elements without scope.

Example
<table>
  <thead>
    <tr>
      <th scope="col">Name</th>
      <th scope="col">Email</th>
      <th scope="col">Phone</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">John Doe</th>
      <td>john@doe.com</td>
      <td>1234567890</td>
    </tr>
    <tr>
      <th scope="row">Jane Doe</th>
      <td>jane@doe.com</td>
      <td>9876543210</td>
    </tr>
  </tbody>
</table>

⚠️ Note: <frame>, <frameset>, and <noframes> are obsolete. Use <iframe> and CSS instead, or use server-side includes to generate complete pages with the various invariant parts merged in.

Provide a label for a frame so users can determine which frame to enter and explore in detail.

This is different than the <title> element. The attribute facilitates navigation among frames and the element clarifies the user's current location.

Use the title attribute to provide an accessible name for form controls when the visual design does not include text on the screen that can be associated with the control as a label.

Example
<input type="text" title="Area code" size="3" value="">
<input type="text" title="First three digits of phone number" size="3" value="">
<input type="text" title="Last four digits of phone number" size="4" value="">

<img> elements can be safely ignored by Assistive Technology if no title attribute is used and the alternative text is set to null (e.g. alt="").

Use section headings to convey the structure of the content. Avoid skipping levels in the sequence of headings.

⚠️ Note: <frame>, <frameset>, and <noframes> are obsolete. Use <iframe> and CSS instead, or use server-side includes to generate complete pages with the various invariant parts merged in.

Use frames to organize elements to provide a mechanism for easily bypassing blocks of repeated content.

If the site uses framesets, organize the blocks of content into separate frames. Make certain that the repeated blocks of content appear in the same <frame> within the <frameset> of each Web page. In addition, each <frame> element must have a title attribute to describe the content of the frame.

Form controls can be grouped by enclosing them within the <fieldset> element. All controls within a given <fieldset> are then related.

The first element inside the <fieldset> must be a <legend> element, which provides a label or description for the group.

This is most important for related radio buttons and checkboxes, or where a group of controls within a larger form requires an additional heading to provide a description specific to that particular group.

⚠️ Note: summary on <table> is obsolete. Use these techniques instead.

Provide a brief overview of how data has been organized into a table or a brief explanation of how to navigate the table.

Provide closing tags for all elements that require them.

Ensure there are no closing tags for all elements that forbid them.

Ensure opening and closing tags of all elements are correctly nested.

⚠️ Note: Only applies if you're using the XML syntax for writing HTML.

Avoid key errors that are known to cause problems by checking document well-formedness with an XML parser.

ℹ️ Note: Redirects are preferably implemented on the server side.

Enable redirects on the client side without confusing the user.

Example
<head>
  <!-- Immediate (0 seconds) redirect to another URI (example.com) -->
  <meta http-equiv="refresh" content="0; url=https://example.com">
</head>

The <li> enclosing the <a> provides context for an otherwise unclear link when the <li> is the nearest enclosing block-level ancestor element.

Example
<ul>
  <li>
    Our biggest discounts of the year:
    <a href="/winter-sale">The Winter Sale</a>.
  </li>
  ...
</ul>

Same as "Identifying the purpose of a link using link text combined with its enclosing list item". Except <p> provides the context.

The table header cell(s) associated to the <td> enclosing the <a> provides context for an otherwise unclear link when the <td> is the nearest enclosing block-level ancestor element.

Whenever possible, provide link text that identifies the purpose of the link without needing additional context.

The preceding heading to the <a> provides context for an otherwise unclear link.

Whenever possible, provide link text that identifies the purpose of the link without needing additional context.

Same as "Identifying the purpose of a link using link text combined with its enclosing list item". Except the links are in a nested list inside an <li>.

On links that open new windows, provide both a target="_blank" attribute value and information indicating that such link will open in a new window in the link text.

Avoid having an action occur as a side effect of choosing a value for the <select> element.

Instead allow the user to control when an action is performed by selecting a button to perform the action.

Group options together with the <optgroup> element, with the related <option> elements inside that element. Label the group with the label attribute so users will know what to expect inside the group.

The <optgroup> element should be directly inside the <select> element, and the <option> elements directly inside the <optgroup>.

Provide text alternatives immediately before or after all ASCII art, emoticons and/or Leetspeak.

It is also suggested that there be a link to skip over the ASCII art (although this is not required).

Example
:-) (smile)

<abbr title="smile">:-)</abbr>

Use only features that are defined in the specification, in the manner prescribed by the specification, while making sure the content can be parsed.

⚠️ Note: Current browsers and Assistive Technologies do not always provide the information contained in the title attribute to users. Avoid using this technique in isolation until the title attribute has wide-spread support.

Provide context sensitive help for users as they enter data in forms by providing the help information in a title attribute. The help may include format information or examples of input.

Provide a symbol or text indicating that the control is required by using the <label> element, or the <legend> for groups of controls associated via <fieldset>.

Example
<label for="firstname">First name (required):</label>
<input type="text" name="firstname" id="firstname">

<label for="lastname">Last name <abbr title="required">*</abbr>:</label>
<input type="text" name="lastname" id="lastname">

<fieldset>
  <legend>Please enter the following (required):</legend>

  <label for="firstname">First name</label>
  <input type="text" name="firstname" id="firstname">

  <label for="lastname">Last name</label>
  <input type="text" name="lastname" id="lastname">
</fieldset>

For each link and form element, check that the name, value, and state are specified as indicated here.

All id attribute values must be unique on the web page to avoid key errors that are known to cause problems for Assistive Technologies.

Check that no attribute occurs more than once on any element to avoid key errors that are known to cause problems for Assistive Technologies.

Use the <track> element to specify a captions timed text track for a <video> element.

⚠️ Note: As of February 2019 there is no native support in browsers for this technique. Except via JavaScript polyfills.

Use the <track> element to specify a descriptions timed text track for a <video> element.

Use a <nav> to make groups of links easier to locate and skip past by users of Assistive Technology.

When the <nav> element is employed more than once on a page, distinguish the navigation groups by using an aria-label or aria-labelledby attribute.

Use the autocomplete attribute to hint the browser how to help users fill forms based on earlier user input.

CSS

Visual appearance may be enhanced via style sheets while still maintaining a meaningful presentation when style sheets are not applied.

Supplement the link text by adding additional text that describes the unique function of the link and styling the additional text so that it is not rendered on the screen by browsers that support CSS.

Avoid visibility: hidden; and display: none; since those hide text from Assistive Technology.

Example
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  clip-path: inset(100%);
  white-space: nowrap;
}
<button type="button">
  <span aria-hidden="true">&times;</span>
  <span class="sr-only">Close</span>
</button>

visual appearance of spacing in text may be enhanced via style sheets while still maintaining meaningful text sequencing.

The CSS letter-spacing property helps developers control the amount of white space between characters. It's recommended over adding blank characters since they can change the meaning and pronunciation of a word.

Add purely decorative images and images used for visual formatting to Web content without requiring additional markup within the content by using CSS properties like:

  • background
  • background-image
  • content with the ::before and ::after pseudo-elements
  • list-style-image

This is not appropriate for images that are meant to convey information or provide functionality.

Specify text font size proportionally so that browser can scale content effectively.

If a font-size is specified for the <body> element, all other elements inherit that value, unless overridden by a more specific selector.

Specify a named font size that expresses the relative font size desired.

These values provide hints so that the browser can choose a font-size relative to the inherited font-size:

  • xx-small
  • x-small
  • small
  • medium
  • large
  • x-large
  • xx-large
  • larger
  • smaller

Specify text font size in em units so that browser can scale content effectively. The em is a property of the font, it scales as the font changes size.

If a font-size is specified for the <body> element, all other elements inherit that value, unless overridden by a more specific selector.

Highlighting an element that has focus or is hovered over can provide information such as the fact that the element is interactive or the scope of the interactive element.

The dynamic pseudo-classes :hover, :active, and :focus can be used for this.

Ensure text-based form controls resize when text size is changed in the browser by using relative units.

Avoid using spacer images (e.g. 1x1 pixel transparent GIFs) for layout control, indenting or creating space. Use CSS margin and padding instead.

Use the CSS text-align property to align blocks of text either left or right.

Ensure that CSS is used in a way that allows users to view content in such a way that line length can average 80 characters or less.

Provide line spacing between 1.5 to 2 to allow people with cognitive disabilities that have trouble tracking lines of text.

Example
p {
  line-height: 1.5; /* or 150% */
}

The following CSS properties are useful to style text and avoid the need for text in images:

  • font-family: specifies a prioritized list of one or more font family names
  • text-align: sets the horizontal alignment of a block element or table-cell box
  • font-size: sets the size of the font
  • font-style: sets whether a font should be styled with a normal, italic, or oblique face
  • font-weight: sets the weight (or boldness) of the font
  • color: sets the foreground color value of an element's text and text decorations
  • line-height: sets the height of a line box
  • text-transform: specifies how to capitalize an element's text
  • letter-spacing: sets the spacing behavior between text characters
  • background-image: sets one or more background images on an element
  • ::first-line: pseudo-element that applies styles to the first line of a block-level element
  • ::first-letter: pseudo-element that applies styles to the first letter of the first line of a block-level element, but only when not preceded by other content (such as images or inline tables)
  • ::before and ::after: pseudo-elements used to insert decorative non-text content before or after blocks of text

Some Web pages use colors to identify different groupings. The objective is to allow users to select specific color combinations for the text and background of the main content while retaining visual clues to the groupings and organization of the web page. When a user overrides the foreground and background colors of all the text on a page, visual clues to the grouping and organization of the Web page may be lost, making it much more difficult to understand and use.

When an author does not specify the colors of the text and background of the main content, it is possible to change the colors of those regions in the browser without the need to override the colors with a user style sheet. Specifying the text and background colors of secondary content means that the browser will not override those colors.

Specify the width of text containers using percent values to enable users to increase the size of text without having to scroll horizontally to read that text.

Specify borders and layout using CSS and leave text and background colors to render according to the user's browser and/or operating system settings.

Ensure the order of content in the source code is the same as the visual presentation of the content. When the source order matches the visual order, everyone will read the content and interact with it in the same (correct) order.

Specify the width and/or height of containers, that contain text or that will accept text input, in em units to allow browsers that support text resizing to resize the text containers in line with changes in text size settings.

When some aspect of the default presentation of a Web page does not meet a Success Criterion, it is possible to meet that requirement using the "Alternate Version" clause in the conformance requirements (Conformance Requirement 1). For some requirements, invoking a style switcher via a link or control on the page that can adjust the presentation so that all aspects of the page conform at the level claimed allows authors to avoid having to provide multiple versions of the same information.

CSS can be used to replace structured HTML text with images of text, in a technique commonly referred to as "CSS image replacement".

Use layout techniques that adapt to the available viewport space, like Flexbox, to present content without introducing a horizontal scroll bar at a width equivalent to 320 CSS pixels or a vertical scroll bar at a height equivalent to 256 CSS pixels.

Same as "Using CSS Flexbox to reflow content". But with CSS Grid and Media Queries.

Using a human readable text link, rather than a long URL, is better for usability and accessibility.

Having said that, you may use CSS properties overflow-wrap and word-wrap to help wrap the text in a long URL.

⚠️ Note: Keyboard users tabbing backwards, on a page with a sticky header, to reach interactive elements higher up will often mean that the focus becomes invisible once it moves behind the sticky header.

Present content with sticky headers and footers when there is enough space by using min-height, max-height and min-width media queries techniques that adapt to the available space of the viewport.

Content needs to allow spacing changes without loss of content or functionality by allowing the elements containing the text to expand as needed.

Where text is not intended to wrap, authors should either size containers to a have a value greater than the default width of the text, or allow the containers to expand in the direction of text.

If elements must use a fixed width, a safe value is 20% wider than the default maximum width.

Content needs to allow spacing changes without loss of content or functionality, so text containers must either have room for the text to expand or the container must be able to expand.

In English languages, if authors do not set the CSS height property, it can help ensure paragraphs expand.

The basic principles of fitting images are to:

  1. Define the max-width property for images, and;
  2. Define the height property for images, so they enlarge or shrink in the available space and respond to zoom levels.

When space is limited in the viewport for the label and input to sit next to each other horizontally, they may be changed to a vertical alignment by setting width, max-width and Flexbox to adapt to the available space.

Allow users to prevent animation (e.g. "parallax scrolling") from being displayed on Web pages, via the use of the prefers-reduced-motion media query.

Example
@media (prefers-reduced-motion: reduce) {
  /* disable motion here */
}

Create a two-color focus indicator that has sufficient contrast against any background color with the text-shadow and outline CSS properties with the :focus CSS pseudo-class.

Example
.element:focus {
  box-shadow: 0 0 0 1px white;
  outline: dotted;
}

The aria-describedby property may be used to attach descriptive information to one or more elements through the use of an id reference list. The id reference list contains one or more unique element ids.

The aria-required property indicates that user input is required before submission and can have values of true or false.

The WAI-ARIA specification provides an informative description of each role, how it relates to other roles, and the states and properties for each role. When rich internet applications define new user interface widgets, exposing the roles enables users to understand the widget and how to interact with it.

The WAI-ARIA specification provides a normative description of each attribute, and the role of the user interface elements that they support. When rich internet applications define new user interface widgets, exposing the state and property attributes enables users to understand the widget and how to interact with it.

⚠️ Note: aria-label may be disregarded in situations where aria-labelledby is used for the same object.

⚠️ Note: aria-label will override any native naming such as alt on <img> or a <label> associated with a form field using the for attribute

The aria-label attribute provides the text label for an object, such as a button. When a screen reader encounters the object, the aria-label text is read so that the user will know what it is.

When applied on links, aria-labelledby can be used to identify the purpose of a link that may be readily apparent for sighted users, but less obvious for screen reader users.

The specified behavior of aria-labelledby is that the associated label text is announced instead of the link text (not in addition to the link text). When the link text itself should be included in the label text, the ID of the link should be referenced as well in the string of IDs forming the value of the aria-labelledby attribute.

Describe the purpose of a link using the aria-label attribute. The aria-label attribute provides a way to place a descriptive text label on an object, such as a link, when there are no elements visible on the page that describe the object. If descriptive elements are visible on the page, the aria-labelledby attribute should be used instead of aria-label.

One particular use of aria-labelledby is for text inputs in situations where a meaningful label should consist of more than one label string.

Authors assign unique ids to the label strings to be concatenated as the label for the input element. The value of the aria-labelledby attribute is then a space-separated list of all ids in the order in which the label strings referenced should be read by screen readers.

The aria-labelledby attribute associates an element with text that is visible elsewhere on the page by using an ID reference value that matches the ID attribute of the labeling element.

Use landmark roles (or "landmarks") to programmatically identify sections of a page and help Assistive Technology users orient themselves to a page and help them navigate easily to various sections of a page.

Provide a way for Assistive Technologies to identify a piece of content as a heading by applying role="heading" to an element. If there is more than one heading on the page and the heading hierarchy is defined through the visual presentation, the aria-level attribute should be used to indicate the hierarchical level of the heading. However, when possible, use native heading mark-up instead.

Use the aria-labelledby attribute to provide a way to associate an section of the page marked up as a region or landmarks with text that is on the page that labels it.

Elements can be given the attribute aria-label to provide an accessible name for situations when there is no visible label due to a chosen design approach or layout but the context and visual appearance of the control make its purpose clear.

Disclaimer

This document is a summarized list of informative techniques for accessible Web content.

It is best used alongside "How to Meet WCAG 2.1" and "Web Content Accessibility Guidelines (WCAG) 2.1" for meeting the success criteria established in the guidelines. For more on techniques click here.

Credit

Original W3C document: Techniques for WCAG 2.1

Copyright © 2017-2018 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.