WCAG 1.3.1 Info and Relationships: headings, lists, labels

WCAG 1.3.1 Info and Relationships is a Level A criterion: structure that is clear from how a page looks, such as headings, lists, table headers, form labels, field groups and page regions, must also be in the code so assistive technology can present it. Skipped heading levels alone are best practice, not a 1.3.1 failure.

Published . Last reviewed .

Most of what a sighted visitor takes in at a glance, which text is a heading, which items form a list, which header belongs to which table column, which label goes with which field, is told by size, weight, spacing and position. Criterion 1.3.1 asks that the same facts exist in the markup. This page covers what the criterion requires, what W3C lists as failures and sufficient fixes for headings, lists, tables, form labels, field groups and landmarks, why a skipped heading level is not a failure on its own, real failing and passing code, a step-by-step test, and exactly what GotAlt's tools check and cannot check.

What WCAG 1.3.1 requires

Success criterion 1.3.1 asks that information, structure and relationships conveyed through presentation "can be programmatically determined or are available in text" (W3C, WCAG 2.2). It is Level A, has been in WCAG since WCAG 2.0, and is kept in 2.1 and 2.2.

W3C's Understanding 1.3.1 defines "programmatically determined" as "determined by software from author-supplied data" in a way that different user agents, including assistive technologies, can present. Its intent is that relationships implied by visual formatting are "preserved when the presentation format changes", for example when a screen reader reads the page or a user substitutes their own style sheet. One method W3C gives for checking is to "access the information serially in different modalities". Three clarifications from the same page:

  • "Or are available in text" is the fallback for technologies that cannot express a relationship in code, such as a note that "all required fields are marked with an asterisk". W3C says that where the technology supports programmatic relationships, that is "strongly encouraged" over describing them in text.
  • Color values are not covered here. "It is not required that color values be programmatically determined"; color is handled by 1.4.1 Use of Color.
  • Reading order is a different criterion. Whether the sequence in the code makes sense is 1.3.2 Meaningful Sequence.

Because 1.3.1 is Level A, it is inside every target the laws in our register name: WCAG 2.0 AA for Section 508 and Ontario's AODA, and WCAG 2.1 AA for the ADA Title II web rule and, through EN 301 549, the European Accessibility Act. Our laws hub covers each. This page explains a technical standard and is not legal advice.

How often structure is missing

The 2026 WebAIM Million (data collected February 2026) is the standard reference for real-world failure rates. Its structure findings:

Structure findings in the 2026 WebAIM Million
Finding2026 figureEarlier figure
Home pages with a missing form input label51%48.2% in 2025
Form inputs not properly labeled (by label, aria-label, aria-labelledby or title)33.1% of inputs, on pages averaging 6.9 inputsNot reported
Pages with skipped heading levels41.8% of pages; 1,206,444 instances, about one in every 25 headings39% in 2025
Home pages with more than one h118.1%16.3% in 2025
Pages with no headings at all7.5%9.8% in 2025
Home pages with at least one region or landmark84.3%; a main landmark on 46.1%80.5% and 42.6% in 2025

WebAIM states the reason headings matter: "headings are the primary mechanism used by screen reader users to navigate content". It also reports that 94.9% of home pages with at least one h6 had skipped heading levels, which "suggests that most of these headings probably do not reflect the actual document structure". That observation is the key to the skipped-level question below: the skip is usually a symptom of choosing a heading for its size. Missing labels, the first row, are covered under form labels and in our page on the most common accessibility errors.

What you see, and what the code has to say

Visual structure, the markup that carries it, and W3C's named techniques and failures for WCAG 1.3.1
What a sighted visitor seesWhat the code needsSufficient techniquesFailures W3C names
A heading: larger, bolder text that starts a sectionh1 to h6, or role="heading" with aria-levelH42, h1 to h6, ARIA12, role=headingF2, a paragraph styled as a heading, F43, heading markup used for looks
A list: bullets, numbers, a column of itemsul, ol or dlH48, ol, ul and dlNo list-specific failure is named for HTML
A data table: rows and columns with headerstable with th header cells, plus scope or id and headers when neededH51, table markup, H63, scope, H43, id and headers, H39, captionF91, headers not marked up, F90, wrong id and headers, F48, pre used for a table, F46, th or caption in a layout table, F92, role="presentation" on a data table
A label next to a fieldA label tied to the control, or aria-labelledby, aria-label or titleH44, label element, H65, title attribute, ARIA16, aria-labelledbyF111, visible label text but no accessible name
A group of related controls: radio buttons, an address blockfieldset with legend, or role="group" with aria-labelledbyH71, fieldset and legend, ARIA17, grouping roles, H85, optgroup in a selectNo group-specific failure is named
Page regions: header, navigation, main content, footerHTML elements such as header, nav, main and footer, or landmark rolesH101, semantic HTML regions, ARIA11, landmark roles, ARIA20, the region roleNo landmark-specific failure is named
The current page marked in a menuaria-currentARIA26, aria-currentCovered by F2 if only the look conveys it
Emphasis, such as bold or italic that carries meaningstrong, emG115, semantic elements with H49, markup for emphasisF2

The sufficient techniques are examples, not a closed list. W3C states that content can satisfy WCAG "even if it does not use any of the documented techniques". The failures are the reliable part: if your markup matches one, it fails. W3C's Understanding page for 1.3.1 also lists F42, emulating links, and, for plain text, F33, white space used to make columns and F34, white space used to format tables.

Headings

Heading markup does two jobs: it tells assistive technology that the text is a heading, and its level shows how sections nest. W3C's technique H42 has two checks: heading markup is used when content is a heading, and "heading markup is not used when content is not a heading." Both directions are failures. Text that looks like a heading but is a styled p is failure F2. A heading tag chosen only for its font size is F43, whose first example is an address set in an h4 to get large bold type: it "should not be marked as a heading".

Failing, per F2. The look says heading, the markup says paragraph:

<p class="big-bold">Shipping</p>
<p>Orders leave within two days.</p>

Failing, per F43. A heading level used to get smaller type, in a place that is not a section:

<h4>3333 Third Avenue, Suite 300</h4>

Passing. Real heading markup, with CSS controlling the size:

<h2>Shipping</h2>
<p>Orders leave within two days.</p>

Skipped heading levels: advice, not a 1.3.1 failure on its own

Many tools, including ours, report skipped heading levels, and many articles call them a WCAG failure. The WCAG sources say otherwise:

  • W3C's technique G141, Organizing a page using headings, lists 1.3.1 as advisory, not sufficient, and phrases the nesting as guidance: "authors should use headings that are properly nested". The page adds that techniques "are not required to meet WCAG".
  • W3C's WAI tutorial on headings says "skipping heading ranks can be confusing and should be avoided where possible". It also says it is fine to go from a deep heading back up to a higher one, such as an h2 that begins a new section after an h4, "as it closes the previous section".
  • The WCAG 2.2 success criteria never say to keep heading levels in sequence, and none says a page needs exactly one h1. The list of failures W3C documents for 1.3.1 does not include either.

The HTML language rules are stricter than WCAG on this point. The HTML Standard says each heading's level must be less than, equal to or one greater than the heading before it, and it labels an h1 followed by an h3 non-conforming for authors. That is an HTML authoring rule, not a WCAG success criterion, and our heading structure guide covers both.

So a page that goes from h2 to h4 does not fail 1.3.1 for that alone. Why report it? Because it is a good detector of the real failure. A skip is usually a heading picked for its size (F43), and it disrupts the outline people navigate by, which W3C's tutorial calls confusing. GotAlt's free scan lists skipped levels under 1.3.1 as a minor finding for that reason. Read it as a prompt to look at the outline, not as a confirmed failure of the criterion. Whether headings describe their sections is a separate criterion, 2.4.6 Headings and Labels (Level AA).

On the one-h1 convention, the same reasoning applies. WCAG does not require it. We recommend a single h1 that names the page, because W3C's tutorial shows exactly one rank 1 heading in both of its sample layouts and because a missing or doubled h1 is a common sign of a template problem. Our heading structure guide goes deeper.

Lists

Technique H48 asks for ol, ul and dl where content is a list. It notes the limit as well: "not all lists need markup", and a sentence that contains a comma-separated list may not need it. The failure to avoid is the one H48 itself describes, items made to look like a list with asterisks or br elements. H48 notes that some assistive technologies let users move from list to list or item to item, and that a list of links lets screen reader users jump past the whole group. A column of div elements with bullet characters offers neither.

Failing:

<p>* Free returns<br>
* Free shipping over $50<br>
* Two-year warranty</p>

Passing:

<ul>
  <li>Free returns</li>
  <li>Free shipping over $50</li>
  <li>Two-year warranty</li>
</ul>

The reverse also matters. A menu is a list of links, so ul inside nav is correct. Structural markup used for looks misstates the content. The examples in failure F43, structural markup that does not represent relationships, include a blockquote used to indent text that is not a quotation and a fieldset and legend used only to draw a border.

Tables

W3C's tutorial on tables puts the requirement in one line: header cells "must be marked up with <th>", and data cells with <td>. Screen readers use that to announce the row and column headers as a person moves from cell to cell. The rules in practice:

  • Header cells are th. A table where the headers are td cells in bold is failure F91.
  • scope where direction is unclear. H63 says that for simple tables with the headers in the first row or column, "it is sufficient to simply use the th elements without scope". When a table has both row and column headers, set scope="col" and scope="row". This site's own tables do.
  • id and headers for complex tables, with headers that span groups or multiple levels (technique H43). Wrong values are failure F90. W3C also suggests that some users find several simple tables easier to work with than one complex table.
  • A caption is good practice, not a requirement. W3C's caption tutorial says captions and summaries are "not required in every case to meet WCAG". It also says a caption "functions like a heading for a table" and, in a screen reader's tables mode, is the primary way to identify one.
  • Layout tables stay free of data-table markup. Putting th, caption or a summary in a layout table is failure F46, because it states relationships that do not exist. W3C notes WCAG 2 does not prohibit layout tables but recommends CSS layout. Marking a real data table role="presentation" is the opposite error, F92.

Failing. Headers are ordinary cells (F91):

<table>
  <tr><td><b>Plan</b></td><td><b>Pages</b></td></tr>
  <tr><td>Basic</td><td>10</td></tr>
</table>

Passing. Header cells with a direction, and a caption:

<table>
  <caption>Sample plans</caption>
  <tr>
    <th scope="col">Plan</th>
    <th scope="col">Pages</th>
  </tr>
  <tr>
    <th scope="row">Basic</th>
    <td>10</td>
  </tr>
</table>

A grid of div elements styled to look like a table has the same problem as the first example, with no table semantics at all. Either use a real table or give the grid the table roles.

Form labels and groups

A label that sits beside a field is a visual relationship, and 1.3.1 asks for it in code. W3C's technique H44 is sufficient for 1.3.1, 3.3.2 and 4.1.2 alike, which is why one missing label is usually reported against several criteria. In W3C's forms tutorial, the options are:

  • A label with for, where "the for attribute of the label must exactly match the id of the form control". This is the first choice, and the label becomes a larger click target.
  • A label that wraps the control. Fine when the control has no usable id. The tutorial says explicit labels are generally better supported.
  • aria-labelledby or aria-label when there is no visible label text. The tutorial says to use them "only when the label of the control is clear from the surrounding content", such as a search field beside a button that says Search.
  • The title attribute (H65). The tutorial calls it "generally less reliable and not recommended", because some assistive technologies do not treat it as a replacement for a label.

A visible label can also be hidden visually. The tutorial says the label "still needs to be provided within the code" and shows how to clip it off screen, for a search box whose purpose is obvious from the button beside it. A hidden label satisfies 1.3.1 and 4.1.2, but W3C's technique H44 says that for 3.3.2 Labels or Instructions "the label element must be visible". A placeholder is not on the tutorial's list. GotAlt's tools do not count one as a label.

Failing. The word "Email" is next to the field but not connected to it. This is the situation W3C documents as F111, a visible label with no accessible name, and speech input users cannot say the label to reach the field:

<span>Email</span>
<input type="email" name="email">

Failing. A label exists, but its for does not match the field's id:

<label for="mail">Email</label>
<input type="email" id="email">

Passing:

<label for="email">Email</label>
<input type="email" id="email">

Groups of controls

Radio buttons and checkboxes that answer one question are related, and the question is the relationship. W3C's technique H71 uses fieldset and legend, and W3C's grouping tutorial says "radio button groups should always be grouped using <fieldset>". Groups also tell apart repeated labels, such as the same "Street" field in a shipping and a billing address. The tutorial's caution: some screen readers read the legend with every control, once, or rarely not at all, so keep the legend short and make each label clear without it. role="group" with aria-labelledby (technique ARIA17) is the alternative when a fieldset does not suit the layout.

Failing. A caption in a paragraph, not tied to the radio buttons:

<p>Output format</p>
<input type="radio" name="f" id="csv">
<label for="csv">CSV file</label>

Passing:

<fieldset>
  <legend>Output format</legend>
  <input type="radio" name="f" id="csv">
  <label for="csv">CSV file</label>
</fieldset>

Required fields and other cues carried by looks

W3C's own examples of 1.3.1 include required fields. Labels in red with an asterisk are fine when the instructions say so in text and the information also reaches software; red alone would fall under 1.4.1 as well. Writing "(required)" in the label text and adding the required attribute covers both people and software:

<label for="email">
  Email (required)</label>
<input type="email" id="email" required>

The same logic applies to a menu that marks the current page only with bold type. Add aria-current="page" to that link (technique ARIA26).

Landmarks

Header, navigation, main content and footer are visual regions, and landmarks are how they reach software. The ARIA Authoring Practices Guide lists the HTML elements that create them:

HTML elements and the landmark roles they create, per the ARIA Authoring Practices Guide
HTML elementLandmark role
header, in the context of bodybanner
navnavigation
mainmain
asidecomplementary
footer, in the context of bodycontentinfo
section with an accessible nameregion
searchsearch
  • Context matters. A header inside article, aside, main, nav or section is not a banner, and a section without an accessible name is not a landmark.
  • Label repeats. If a role is used more than once, "provide each instance of that landmark with a unique label", for example <nav aria-label="Main"> and a second nav labeled "Breadcrumb". Leave the role word out of the label: "Site Navigation" would be announced as "Site Navigation Navigation".
  • Put the content inside them. The guide describes putting all perceivable content in a landmark as one of the most effective ways to make sure assistive technology users do not overlook it.
  • What the criterion requires. Landmarks are listed as sufficient techniques (H101, ARIA11, ARIA20), but none of the failures W3C names for 1.3.1 is about missing landmarks. They are the usual way to expose page regions and also support 2.4.1 Bypass Blocks; whether a particular page without them fails is a judgment about what its layout conveys.

How to test WCAG 1.3.1, step by step

  1. List the visual structure. Scan the page and write down every heading, list, table, form field and group, and every region, plus anything marked only by a style: a bold lead-in, bullets, a colored or starred label, a highlighted menu item.
  2. Read the accessibility tree. In Chrome's developer tools, the Accessibility tab has a "Show accessibility tree" toggle that replaces the DOM tree with the tree exposed to assistive technology, and Firefox's Accessibility Inspector shows the same. Check each item from step 1 appears with the right role.
  3. Print the heading outline. This shows levels and text in order:
document.querySelectorAll(
  "h1,h2,h3,h4,h5,h6,[role=heading]")
  .forEach(h => console.log(
    h.getAttribute("aria-level") || h.tagName,
    h.textContent.trim().slice(0, 60)));
  1. Find fields with no label element. Each result still needs a look for an aria-label or aria-labelledby. The labels property lists the label elements associated with a control:
const sel = "input:not([type=hidden])"
  + ":not([type=submit]):not([type=button])"
  + ":not([type=reset]):not([type=image])"
  + ", select, textarea";
for (const f of document.querySelectorAll(sel)) {
  if (!f.labels.length) {
    console.log(f.outerHTML.slice(0, 80));
  }
}
  1. Try the quick keys. Screen reader users move through these structures by element type. The table below uses NVDA's keys, from WebAIM's NVDA guide. If a key finds nothing where you can see the structure, the code does not say it.
  2. Walk a table cell by cell and listen for the row and column headers changing. In a form, tab through and listen for each label; with grouped controls, listen for the group name.
  3. Check cues that rely on look. For each color, icon, bold style or position that carries meaning, find the text or markup that carries it too.
  4. Run the automated checks listed in the next sections to catch the mechanical cases, then repeat after the page changes state, because menus, tabs and scripts add structure that a one-time check never saw.
NVDA quick keys for the structures 1.3.1 covers (WebAIM's NVDA guide)
StructureKeyYou should be able to
HeadingsH, or 1 to 6 for a levelLand on each visual heading, at the right level
ListsLReach each visual list and hear that it is a list
TablesTReach each data table, then hear headers as you move through the cells
Form controlsFLand on each field and hear its label
LandmarksDReach the header, navigation, main content and footer
Everything at onceNVDA+F7See page links, headings and landmarks in the Elements List

Our guide to testing website accessibility fits this into a full manual pass.

Common false positives and false negatives

Where automated structure results mislead
SituationWhat tools tend to reportWhat is actually true
Heading levels skip, h2 to h4Failure of 1.3.1Advice, not a failure on its own. Look for a heading chosen for size (F43).
A page has two h1 elementsFailureNot a WCAG requirement. We still recommend one h1 that names the page.
A bold p that looks like a headingNo findingFailure F2. There is no heading tag to inspect, so only a person comparing the page with its markup finds it.
A heading hidden with display: noneCounted as a real headingTools that read HTML do not apply CSS. A hidden h1 can make the outline look correct to a tool while no screen reader user ever meets it, because display: none and visibility: hidden hide text from assistive technology as well (W3C, technique C7). A visually hidden heading, clipped off screen, is still announced.
A field with an aria-label and no visible labelPass, because it has a nameHas a name for software, but W3C says use it only where the label is clear from the surrounding content.
A field with only a placeholderFlagged by our scan and bookmarkletW3C's label techniques use a label element, aria-label, aria-labelledby or title, not placeholder text.
A field whose aria-labelledby points to an id that does not existPass in checks that only see that the attribute is present, including our free scanThe field has no accessible name. W3C documents it as part of F111.
A label with the wrong forOften "a label exists"The control has no label. Checks that look only for label elements miss it.
An empty label elementPassA label with no text names nothing. Automated checks that only match for to id do not read the text.
A data table with td headersOften no findingFailure F91. Whether a table is data or layout is a judgment for a person.
A table with no captionMissing captionNot required in every case. A missing th is the failure.
A page with no landmarksFailureNo named failure for it; landmarks are a sufficient technique, not the only one.
Two unlabeled nav regionsPassLandmarks of the same role should each have a unique label.

What GotAlt's tools check, and what they cannot see

Headings and form labels are two of the structures a program can read from the HTML, and our tools cover those two. Nothing in GotAlt checks list markup, table header markup, field groups or landmarks in a web page.

GotAlt tools and WCAG 1.3.1 coverage
ToolWhat it checksWhat it cannot see
Heading checkerEnter a page address or paste HTML. Draws the outline of h1 to h6 elements and flags no h1, more than one h1, skipped levels and empty headings. Its severity labels for the h1 count and skipped levels reflect our recommendations, not WCAG failures. Pasted HTML never leaves your browser.Whether a heading's wording is any good. Text styled to look like a heading (F2), since there is no tag to find. role="heading" elements. Headings hidden by CSS are counted, and headings added by JavaScript are missed unless you paste the rendered HTML.
Free scanThree of its 16 rule-based checks, run across up to 3 pages: a form field with no label (a label tied by for and id or wrapped around the field, aria-label, aria-labelledby or title), a missing h1, and skipped heading levels. Placeholder text does not count as a label.Whether a label's text is meaningful or even present. The label check is approximate: it matches for values to ids and counts fields inside labels without building the full page tree. The report files the label check under 3.3.2, although a missing label also fails 1.3.1 and 4.1.2. Lists, tables, groups and landmarks are not checked.
Accessibility bookmarkletReads the rendered page you have open, including logged-in pages. Lists the heading outline (including role="heading" with aria-level) and flags a missing h1, skipped levels and empty headings. Flags fields with no label and fields labeled only by a placeholder.Lists, tables, groups and landmarks. Whether the structure matches what the page shows. It sees the page once, in its current state.
Deep auditReads the page's heading outline and judges whether each heading describes the content that follows. That is 2.4.6, not 1.3.1. It does not flag a heading for its level number.Markup structure. Up to 30 headings on a page are sent to the model.
PDF checkerFor PDFs: whether a tag structure exists, whether heading tags exist and skip levels, and whether tables have header cells (advisory). See also our accessible PDF guide.Whether the tags are right, or in reading order. Not a PDF/UA test.

A clean result means these checks found nothing, not that a page meets 1.3.1 or any law. The criterion is about every relationship a page shows, and only a person comparing the page with its structure can say whether all of them are in the code. Our page on why rule scanners miss issues covers the wider gap.

For every criterion in one place, see WCAG 2.2 criteria explained and the WCAG 2.2 checklist. For the Level A and AA picture on each platform, see our guides for Shopify, WordPress, Wix, Squarespace and Webflow.

Questions about WCAG 1.3.1

Is a skipped heading level a WCAG 1.3.1 failure?

Not on its own. W3C's technique G141 lists nesting headings properly as advisory for 1.3.1, and its WAI tutorial says skipping ranks "should be avoided where possible". A skip often points to a heading chosen for its size, which is failure F43, so it is worth checking. It is guidance, not a failure of the criterion by itself.

Does a page need exactly one h1?

WCAG does not require it. We recommend one h1 that names the page: W3C's tutorial shows one rank 1 heading in both of its example layouts, and a missing or repeated h1 often signals a template problem.

Do I need scope on every table header?

No. W3C's technique H63 says that for simple tables with headers in the first row or column, it is sufficient to use th elements without scope. Use scope="col" and scope="row" when a table has both row and column headers, and id with headers for complex tables.

Is a placeholder a label?

No. W3C's tutorial and techniques use a label element, aria-labelledby, aria-label or title. A placeholder is not on that list, and GotAlt's scan and bookmarklet both flag a field that has only a placeholder.

Does every table need a caption?

No. W3C's tutorial says captions and summaries are not required in every case to meet WCAG, but a caption works like a heading for a table and helps screen reader users find it. What is required is that header cells are marked up, not the caption.

Are landmarks required?

Landmarks are one of W3C's sufficient techniques for 1.3.1 (H101, ARIA11, ARIA20), and none of the failures it names for the criterion is about missing landmarks. They are the usual way to expose page regions and they help with 2.4.1 Bypass Blocks. If you use the same landmark more than once, give each a unique label.

Is a paragraph styled to look like a heading a failure?

Yes. W3C's failure F2 describes exactly that: changes in text presentation convey meaning without appropriate markup. The fix is to use the real heading element and style it with CSS.

Check the rest of your site for free

The free scan checks form labels, headings and missing alt text, plus page language, link text and more: 16 rule-based checks on up to 3 pages. The free scan does not check lists, tables, field groups or landmarks, so test those with the manual steps above. No signup.

Scan my site for free See a real report first