WCAG 1.3.1: Info and Relationships
Sighted users read structure at a glance: a heading is bigger, a list has bullets, a table lines data up in a grid. This criterion asks that the same structure and relationships be carried in the code, not just the pixels, so a screen reader can announce them and let people navigate by them. It is the foundation almost every other accessibility feature is built on.
The success criterion, in full
Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
“Structure” is how content is grouped and organised — headings, lists, paragraphs, sections. “Relationships” are the meaningful connections between pieces — a label belongs to a field, a header cell governs a column, an item belongs to a list. The rule: wherever those are shown visually, they must also exist in the markup (programmatically determined) or be stated in words (available in text). This is a Level A criterion, part of WCAG since 2.0.
Who this helps
Structure carried in the code is what lets assistive technology present a page as something more than an undifferentiated wall of text. When the relationships are programmatic, everyone who cannot rely on visual layout benefits:
Screen reader users
They navigate by structure — pulling up a list of headings, jumping to the next list or table, moving cell by cell. Without real semantics none of those shortcuts work and the page reads as one flat stream.
Braille display users
Refreshable braille conveys role and level information (heading, list item, table cell) alongside the text, so correct markup is the only thing that tells a deafblind reader how the content is organised.
Low-vision and reflow users
People who zoom to 400% or reflow content to a single column rely on real headings and landmarks to keep their place; visual-only structure collapses when the layout is restyled.
People with cognitive and learning disabilities
Clear, programmatic structure lets reading tools, outliners, and reader modes break long pages into navigable chunks and summarise them reliably.
Voice-control users
Commands like “click the Email field” or “show headings” depend on fields having real labels and sections having real headings the software can target by name.
Search engines and automation
Crawlers, reader modes, and AI assistants infer meaning from semantic markup — proper headings, lists, and tables also improve how your content is indexed and summarised.
What the requirement covers
1.3.1 spans every kind of structure and relationship a page conveys visually. The consistent test is: if a sighted user learns something from the way content looks or is arranged, that same information must be available in the markup or in text. The main relationships it covers:
- Headings and sections. Section titles must be real heading elements (h1–h6) in a logical, non-skipping order, so the document outline is programmatic. Large bold text is not a heading.
- Lists and groups. Sequences of related items belong in ul, ol, or dl with li — this exposes the item count and lets users skip the group. Lines separated by <br> or divs are not a list.
- Data tables. Tabular data needs <table> with <th> header cells, scope (or headers/id for complex tables), and ideally a <caption>. This binds every value to its row and column header. Reserve tables for data, not layout.
- Form labels and grouping. Every control needs a programmatically associated name — a <label for> tied to the input’s id (or aria-label/aria-labelledby). Related controls, such as a set of radio buttons, are grouped with <fieldset> and named with <legend>.
- Landmarks and regions. Page regions should use landmark elements — <header>, <nav>, <main>, <aside>, <footer> — so assistive tech can list and jump between the major areas of the page.
- Emphasis and meaning. Where emphasis carries meaning, use <em> and <strong> rather than presentational <i>/<b> or CSS alone. Required or errored fields must convey that state in text or ARIA, not colour or position only.
Semantics first, ARIA to fill the gaps
Native HTML elements carry their roles and relationships for free and stay in sync with the visuals — a real <button> is announced as a button, focusable, and operable by keyboard without any extra code. Reach for ARIA (role, aria-labelledby, scope) only when HTML cannot express the relationship or you are building a custom widget. Using ARIA to retrofit meaning onto a pile of <div>s is fragile and easy to get wrong.
“Or available in text”
The criterion offers an alternative to markup: state the relationship in words. If a complex visual relationship cannot be fully captured in semantics, a plain-text description that conveys the same information also satisfies 1.3.1 — for instance, a sentence that explains what a diagram shows. In practice, native semantics are more robust and reusable, so prefer them and use the text route only where structure genuinely cannot express the relationship.
Pass and fail examples
✓ Passes 1.3.1
- Section titles marked up as h2/h3 in a logical, non-skipping order.
- A navigation menu built from
<ul>and<li>inside<nav>. - A data table with
<th scope>, a caption, and cells bound to headers. - Each input given a
<label for>tied to its id. - Required fields marked with a visible “(required)” and
aria-required, not colour alone.
✗ Fails 1.3.1
- A “heading” that is really a bold, large
<div>. - A list built from
<br>or divs with typed bullets. - Data laid out as a CSS grid of divs with no
<th>or header relationship. - An input whose only “label” is placeholder text or nearby loose text.
- Status or required-state shown by colour or position alone, with no text or ARIA equivalent.
Code examples
A fake heading vs. a real one
Styling a <div> to look like a heading fools the eye but not the accessibility tree. Use a real heading element so the outline is programmatic.
<!-- ✗ Looks like a heading, announced as plain text -->
<div class="text-2xl font-bold">Billing history</div>
<p>…</p>
<!-- ✓ Real heading: appears in the heading list, navigable by H -->
<h2>Billing history</h2>
<p>…</p>Associating a label with its field
Text sitting next to an input is not connected to it. Tie the <label> to the input with matching for and id.
<!-- ✗ Loose text + placeholder: field announces only "edit text" -->
<div>Email address</div>
<input type="email" placeholder="Email address">
<!-- ✓ Programmatic association: field is named "Email address" -->
<label for="email">Email address</label>
<input type="email" id="email">
<!-- ✓ Related controls grouped and named -->
<fieldset>
<legend>Preferred contact method</legend>
<label><input type="radio" name="contact" value="email"> Email</label>
<label><input type="radio" name="contact" value="phone"> Phone</label>
</fieldset>A grid of divs vs. a real data table
Laying data out with CSS loses every header-to-cell relationship. A real table with <th scope> lets a screen reader announce “Revenue, February: $18,000.”
<!-- ✗ Visual-only table: no header relationships -->
<div class="grid">
<div class="cell head">Month</div>
<div class="cell head">Revenue</div>
<div class="cell">February</div>
<div class="cell">$18,000</div>
</div>
<!-- ✓ Real data table with headers and scope -->
<table>
<caption>Monthly sales</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Revenue</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">February</th>
<td>$18,000</td>
</tr>
</tbody>
</table>Interactive demo
Switch between headings, lists, tables, and forms to compare semantic markup with a visual-only version that renders identically. Reveal the screen reader output to see what each one actually conveys to assistive technology.
Real heading elements let screen reader users pull up a heading list and jump between sections. Text that only looks like a heading is invisible to that map.
✓ Semantic markup
Main Page Title (h1)
Section Heading (h2)
Subsection (h3)
Another Section (h2)
✗ Visual-only markup
Main Page Title (styled div)
Section Heading (styled div)
Subsection (styled div)
Another Section (styled div)
Reveal what each version conveys to assistive technology.
Why the visual-only version fails 1.3.1
- Uses bold or large text instead of h1–h6 elements
- Screen readers cannot build a heading map or jump by heading
- Nesting and hierarchy are conveyed only by font size, which is visual-only
Common failures
- Using bold or larger text (a styled div or span) as a heading instead of a real h1–h6 element.
- Skipping heading levels — jumping from h2 to h4 — so the programmatic outline no longer matches the content.
- Building lists from <br> tags or divs with typed bullets, so no list, item count, or grouping is exposed.
- Laying out tabular data with CSS grids or divs, leaving no header-to-cell relationship for screen readers.
- Data tables with no <th>, no scope, or missing captions, so values have no header context.
- Using a placeholder as the only label, which disappears on input and is not a reliable accessible name.
- Labels placed near a field but not associated with it via <label for>/id or aria-labelledby.
- Conveying meaning with colour or position alone (required = red, status by column) with no text or ARIA equivalent.
- “Div soup” — building the whole page from generic divs and spans instead of landmarks, headings, and lists.
- Bolting on ARIA roles to fake semantics when a native element would do, often introducing contradictory or broken roles.
How to test for 1.3.1
- 1
Run an automated scan first
Tools like axe DevTools, WAVE, and Lighthouse catch missing table headers, unlabelled form fields, empty headings, and skipped heading levels. Treat this as the floor — automation finds absent structure, not structure that is present but wrong.
- 2
Inspect the heading outline
Use a headings-map tool or your screen reader’s heading list. Confirm every visual heading is a real h1–h6, the order is logical, and no levels are skipped. Anything that looks like a heading but is missing from the map fails.
- 3
Tab through every form
Move keyboard focus into each control and confirm it announces a meaningful name. Click each visible label and check that focus lands in the matching field — if it does not, the label is not associated.
- 4
Inspect tables in a screen reader
Navigate data tables cell by cell (for example Ctrl+Alt+arrows in NVDA/JAWS) and confirm the correct row and column headers are announced with each value. A flat read-out with no header context is a failure.
- 5
Listen to the whole page
With a screen reader, navigate by headings (H), lists (L), regions/landmarks, and tables (T). The structure you hear should match the structure you see — lists announced as lists, sections reachable as landmarks.
- 6
Check colour- and position-only meaning
For anything conveyed by colour, position, or styling alone (required fields, status, emphasis), confirm the same information is present in text or ARIA so it survives when the visuals are stripped away.
For a structured audit, work through the full WCAG 2.2 checklist.
Related Success Criteria
Content can be presented in a meaningful sequence without losing meaning.
Instructions don't rely solely on sensory characteristics of components.
Content does not restrict its view to a single display orientation.
The purpose of input fields can be programmatically determined.
The purpose of User Interface Components can be programmatically determined.
Frequently asked questions
What does “programmatically determined” mean in WCAG 1.3.1?
It means the information is exposed in the code in a way that browsers and assistive technologies can read and act on — not just painted on the screen for sighted users. A real <h2> is programmatically a heading; a <div> styled to look like a heading is not, even though both look identical. When structure and relationships (this text is a heading, these items form a list, this cell belongs to that column header, this label names that field) are carried by semantic HTML or correct ARIA, a screen reader can announce them and let users navigate by them. If the meaning lives only in visual styling, it is not programmatically determinable and the criterion fails. The escape hatch “or are available in text” means you can instead state the relationship in visible words (for example, a sentence that spells out what a chart shows), but native semantics are almost always the better route.
Should I use semantic HTML or ARIA to satisfy 1.3.1?
Native semantic HTML first, ARIA only to fill genuine gaps. Elements like <h1>–<h6>, <ul>/<ol>/<li>, <table>/<th>/<td>, <label>, <fieldset>/<legend>, <nav>, <main>, and <button> come with built-in roles and relationships that are reliable across browsers and assistive tech, and they cannot fall out of sync with the visuals. ARIA (roles like role="list", properties like aria-labelledby or scope on a header) is a supplement for the cases HTML cannot express, or for custom widgets. The first rule of ARIA is not to use ARIA when a native element will do — a real <button> is safer than <div role="button">. Reaching for ARIA to bolt semantics onto div soup is a common and fragile anti-pattern.
How is 1.3.1 different from 1.3.2 Meaningful Sequence?
1.3.1 is about which relationships exist — that a heading is a heading, a list is a list, a header cell governs its column. 1.3.2 Meaningful Sequence is about the order those pieces are read in: when the reading order matters for comprehension, the DOM order (what a screen reader follows) must match the intended logical order, regardless of how CSS positions things visually. You can pass 1.3.1 by marking everything up correctly and still fail 1.3.2 if, say, CSS flexbox or absolute positioning makes the visual order differ from the source order. Think of 1.3.1 as “the right labels on the parts” and 1.3.2 as “the parts in the right order.”
How is 1.3.1 different from 2.4.6 Headings and Labels?
1.3.1 (Level A) requires that headings and labels exist as real, programmatically determinable structure — an <h2> element, a <label> associated with its input. 2.4.6 Headings and Labels (Level AA) goes a step further and requires that those headings and labels, where present, are descriptive — that they actually describe the topic or purpose. So a page can pass 1.3.1 with a correctly coded but vague heading like “More” and still fail 2.4.6 because the text is not descriptive. 1.3.1 is about the existence and correctness of the structure; 2.4.6 is about the quality of its wording.
How do I make a data table pass 1.3.1?
Use real table markup and connect the data cells to their headers. Wrap the data in <table>, put column and row headings in <th> elements, and give each <th> a scope attribute (scope="col" or scope="row") so assistive technology knows which cells it governs. For complex tables with multiple header levels, use id on the headers and headers="…" on the data cells. Add a <caption> to name the table. Critically, this applies only to tables of data — do not use tables purely for visual layout; if you must, that is a separate concern, but data relationships expressed as a grid of <div>s will fail because there is no header-to-cell relationship for a screen reader to announce.
Why do bold-as-heading and color-as-meaning fail 1.3.1?
Because they encode the relationship purely in presentation, which assistive technology cannot perceive. Bold, larger text looks like a heading to a sighted user, but a screen reader announces it as ordinary body text — the “this is a section heading” relationship exists only in the CSS. Likewise, marking required fields with red text, or indicating status with color alone, communicates nothing to someone who cannot see the color (this also implicates 1.4.1 Use of Color). The fix is to convey the same information in structure or text: a real heading element, an actual list, a visible “(required)” label or aria-required, a status word alongside the color. If sighted users get information from the way something looks, that same information must be available in the markup or in words.