What it asks for, in plain English
If a sighted reader can tell something from the layout, the same thing has to be available to software. A big bold line that is clearly a heading must be an <h2>, not a styled paragraph. A row of items with bullets must be a list. A grid of figures must be a table with header cells. A field's label must be tied to the field.
The same goes for relationships: which label belongs to which input, which radio buttons form a group, which cell belongs to which column, which note is about which field. When the markup carries this, screen readers can announce it, reading mode can keep it and a page can be navigated by heading.
The usual failures are headings made with bold text, lists made with line breaks and dashes, layout tables with no headers, and labels placed next to inputs without being connected to them.
This is an independent explanation. The binding wording is the W3C Recommendation, and the W3C's own Understanding 1.3.1 page has the full intent, techniques and definitions.
Who it affects
Someone using a screen reader jumps between headings to find the section they want, which is impossible when the headings are just bold paragraphs.
A person with dyslexia using reader mode loses the lists and tables entirely when the browser cannot tell what they were.
Someone with a motor impairment using voice control cannot say 'click Email' when the word Email is not actually the field's label.
Example
<p><b style="font-size:1.4em">Opening times</b></p>
<p>Monday to Friday: 9 to 5<br>
Saturday: 10 to 4</p>
<p>Email <input type="email"></p>
To software this is three paragraphs and a field with no name. The heading and the list exist only in your eyes.
<h2>Opening times</h2>
<ul>
<li>Monday to Friday: 9 to 5</li>
<li>Saturday: 10 to 4</li>
</ul>
<label for="email">Email</label> <input id="email" type="email">
Now a screen reader announces 'heading level 2', 'list, 2 items' and 'Email, edit text'. Style the elements however you like.
How to check it
- Open the page in reader mode or switch CSS off. Headings, lists and tables should still look like headings, lists and tables.
- With a screen reader, press the heading shortcut (H in NVDA, or use the VoiceOver rotor). Each visual heading should appear, at a sensible level.
- Click the text of every form label. The cursor should land in its field; if not, the label is not connected.
- For data tables, check the column and row headers are <th> cells, and that a screen reader reads the header when you move across a row.
What Websight checks for 1.3.1
Websight runs these automated checks for 1.3.1:
aria-required-children
Some roles are containers that only mean something with the right children inside: listbox and option, tablist and tab, menu and menuitem, tree and treeitem, table and row.
A
ARIA roles that need a particular parent must sit inside it
aria-required-parent
Some roles only make sense inside a particular parent.
A
Lists must only contain list items
list
A ul or ol tells a screen reader 'list, N items' and lets the person jump item by item.
A
List items must sit inside a list
listitem
An li is only a list item when its parent is a ul, ol or menu.
A
Definition lists must be built from matching terms and descriptions
definition-list
A dl is a list of terms and their descriptions: each dt (the term) is followed by one or more dd (the description).
A
Terms and descriptions must sit inside a definition list
dlitem
dt and dd only mean term and description when they are inside a dl.
A
Never hide the whole page with aria-hidden
aria-hidden-body
aria-hidden="true" tells assistive technology to ignore an element and everything inside it.
A
The headers attribute must point at header cells in the same table
td-headers-attr
The headers attribute on a cell lists the ids of the header cells that describe it.
A
Every table header must describe some data
th-has-data-cells
A th tells screen readers that a cell is the heading for the row or column it sits in.
axe-core also has rules for 1.3.1 that Websight does not run (marked experimental or deprecated):
p-as-heading
A paragraph made bold or bigger looks like a heading to a sighted reader.
not run A
Every data cell in a table needs a header
td-has-header
In a data table, every cell that holds a value needs a header cell that says what the value is.
not run A
Table captions must use the caption element
table-fake-caption
A table's title belongs in a caption element, directly after the opening table tag.
Websight checks that lists, definition lists and tables use the right elements, that table header cells match up with data cells, and that form fields have a label connected to them. It cannot tell that a bold paragraph should have been a heading, or that two fields belong in one group; that is on the manual checklist.
Practical tips
- Pick the element for what the content is, then style it. Never choose <p> and bold because <h2> looks too big.
- Wrap related radio buttons or checkboxes in a <fieldset> with a <legend>; the question is the legend.
- If a table is only there to line things up, use CSS grid instead. If it holds data, give it header cells.
- Use aria-describedby to tie a hint or error message to the field it is about.
Other criteria in guideline 1.3, Adaptable
- 1.3.2 Meaningful Sequence (level A)
- 1.3.3 Sensory Characteristics (level A)
- 1.3.4 Orientation (level AA)
- 1.3.5 Identify Input Purpose (level AA)