WCAG 1.3.1 Info and Relationships — Testing Guide

WCAG 1.3.1 Info and Relationships (Level A) requires that information, structure, and relationships conveyed visually must also be available programmatically. Translated: your app cannot rely on visua

January 04, 2026 · 3 min read · WCAG Guides

WCAG 1.3.1 Info and Relationships (Level A) requires that information, structure, and relationships conveyed visually must also be available programmatically. Translated: your app cannot rely on visual layout alone to communicate — screen readers and assistive tech need the same structure, properly tagged.

What it requires

If a heading looks like a heading, it must be a heading element (

,

, , UIAccessibilityTraitHeader). If a group of form fields belongs together, they should be grouped programmatically (
, accessibilityContainerType). If an icon conveys state, the state must be announced ("unread," "completed").

Layout-only structure is invisible to screen readers.

Common violations

  • Large bold text that "is a heading" but rendered as
    or with no semantic role
  • Paragraphs separated by blank lines but not in distinct

    elements

  • Form labels positioned visually near fields but not programmatically associated
  • Data tables rendered as
    grids with no table semantics
  • Lists rendered as divs with bullets instead of
    • Tabs, accordions, breadcrumbs built without ARIA or native equivalents

    Why it matters

    Screen readers expose structure to navigate. "Jump to next heading" only works if headings are declared. "Read the table row" only works if a table is declared. When structure is missing, users must read the entire page serially — often abandoning before finding what they need.

    Testing

    Web

    • axe-core flags missing semantic roles
    • HTML validator catches improper nesting
    • Landmarks extension (Chrome) shows page regions
    • NVDA + Firefox or VoiceOver + Safari for real experience

    Android

    • Accessibility Scanner flags unlabeled interactives and missing roles
    • TalkBack — tour the screen with it, listen
    • Espresso: AccessibilityChecks.enable() flags missing contentDescription, android:labelFor

    iOS

    • Accessibility Inspector → Audit runs a structural check
    • VoiceOver rotor (settings-rotor / heading-rotor) works only if semantics are set
    • UIAccessibilityTraitHeader, isAccessibilityElement, accessibilityLabel

    How to fix

    HTML:

    
    <!-- Bad -->
    <div class="heading">Settings</div>
    <!-- Good -->
    <h1>Settings</h1>
    

    Form association:

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

    Android XML:

    
    <TextView
      android:textAppearance="?attr/textAppearanceHeadline5"
      android:accessibilityHeading="true"
      android:text="Settings" />
    

    Compose:

    
    Text("Settings", style = MaterialTheme.typography.headlineMedium,
         modifier = Modifier.semantics { heading() })
    

    SwiftUI:

    
    Text("Settings")
        .font(.largeTitle)
        .accessibilityAddTraits(.isHeader)
    

    List and group semantics

    • Use
        /
          for lists, not
          with bullet pseudo-elements
        1. Android: RecyclerView exposes list semantics; custom grids should use accessibilityRole
        2. iOS: accessibilityElements ordering for grouping

      Table semantics

      Data tables need:

      • Table role ( or UITableView or accessibilityContainerType = .dataTable)
      • Header rows / cells (
      • )
      • Caption / summary where useful
      • Layout tables (used only for positioning) must explicitly declare presentational role (role="presentation").

        How SUSA checks 1.3.1

        For web, SUSA runs axe-core which has several 1.3.1 rules (heading-order, label, landmark-one-main, etc.). Violations appear in the report with element selectors and suggestions. For Android, SUSA checks contentDescription, labelFor, and accessibility heading flags. accessibility_user persona drives the exploration with semantic awareness.

        
        susatest-agent test webapp-url --persona accessibility_user --wcag-level AA
        

        Testing order

        1. Automated scan catches the mechanical violations (missing label, missing role)
        2. Manual screen reader tour catches the subtle ones (wrong reading order, confusing group)
        3. Usability test with screen reader users catches the cultural / UX ones (is the structure meaningful, not just valid)

        1.3.1 is the most commonly violated criterion on mobile web. It is also one of the more forgiving to fix — semantic markup is usually a find-and-replace. Make the investment; the downstream wins (better screen reader UX, better SEO, better maintainability) compound.

        Test Your App Autonomously

        Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

        Try SUSA Free