Does Your Code Mean What It Says? Info and Relationships

You can make text look like a heading with CSS - increase the font size, make it bold, add some spacing. Visually, it looks perfect. But to a screen reader, it's just regular text. The structure and meaning that's obvious to sighted users is completely lost.

This is the essence of WCAG 1.3.1: information, structure, and relationships that are conveyed through visual presentation must also be available programmatically - in the code itself.

The Standard

WCAG 1.3.1 Info and Relationships - Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.

In plain English: if you can understand something by looking at it, that understanding needs to be built into the HTML, not just created through visual styling.

Why Semantic HTML Matters

Screen readers and other assistive technologies rely on the underlying HTML structure to understand your page. When you use the right HTML elements for their intended purpose, you're communicating meaning, not just appearance.

What Gets Lost Without Proper Semantics

  • Navigation structure - Screen reader users can't jump between headings if you use <div class="heading"> instead of <h2>
  • Form relationships - Labels don't work if they're just styled text near an input instead of proper <label> elements
  • Data relationships - Table relationships are lost if you fake tables with CSS grid on generic divs
  • List structure - Bulleted items aren't recognized as a list if you use <div> with bullet characters instead of <ul>
  • Interactive elements - Buttons don't behave like buttons if you use <div onclick> instead of <button>

Common Examples of Info and Relationships

Headings Create Document Structure

Headings aren't just bigger, bolder text - they define the hierarchical structure of your content. Screen reader users navigate by jumping between headings to find the section they want.

Wrong approach:

<div class="heading-large">About Our Company</div> <div class="heading-medium">Our History</div>

Right approach:

<h2>About Our Company</h2> <h3>Our History</h3>

The heading level conveys the relationship: "Our History" is a subsection of "About Our Company."

Tables Show Data Relationships

Tables aren't just for layout anymore (thank goodness), but they're essential for showing relationships in tabular data. The relationship between headers and data cells needs to be explicit.

For complex tables with multiple header levels, use scope attributes or headers/id associations to explicitly connect data cells with their headers.

Lists Group Related Items

When items are related and belong together, use list elements. Screen readers announce how many items are in a list and let users skip through them.

Choose the right list type: <ul> for unordered lists, <ol> for ordered lists, <dl> for definition lists with term-description pairs.

Form Labels Connect to Inputs

The relationship between a label and its form field must be explicit, not just visual proximity.

Wrong approach:

<div>Email Address</div> <input type="email" name="email">

Right approach:

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

The for and id attributes create a programmatic relationship that screen readers announce and that makes the label clickable to focus the field.

Buttons vs Links: Purpose Matters

Buttons and links have different purposes and convey different relationships to users:

  • Links navigate to another page or location
  • Buttons perform an action on the current page

Wrong approach:

<div class="button" onclick="submitForm()">Submit</div>

Right approach:

<button type="submit">Submit</button>

Real buttons provide keyboard support, proper focus management, and announce correctly to screen readers. A styled div doesn't.

Visual Relationships Need Code Too

Required Fields

If an asterisk indicates a required field, that needs to be communicated in code too:

<label for="name"> Name <span aria-label="required">*</span> </label> <input type="text" id="name" required>

The required attribute tells assistive technology the field is mandatory, not just the visual asterisk.

Error States

If a field has an error highlighted in red, the error relationship needs to be explicit:

<label for="email">Email Address</label> <input type="email" id="email" aria-invalid="true" aria-describedby="email-error"> <div id="email-error" role="alert">Please enter a valid email address</div>

The aria-describedby connects the error message to the field programmatically.

Grouped Form Fields

When fields are related (like address fields), group them with <fieldset> and <legend>:

<fieldset> <legend>Billing Address</legend> <!-- address fields here --> </fieldset>

This creates a programmatic relationship between the fields and their group label.

ARIA: Use Only When HTML Isn't Enough

ARIA (Accessible Rich Internet Applications) attributes let you add semantic information to elements, but the first rule of ARIA is: don't use ARIA if native HTML works.

Use ARIA when:

  • You're building custom interactive components that don't have native HTML equivalents
  • You need to add information that HTML alone can't convey
  • You're enhancing semantic meaning for complex applications

Don't use ARIA to:

  • Fix problems caused by using the wrong HTML elements
  • Add semantics that native HTML already provides
  • Override native HTML semantics without good reason

Testing Info and Relationships

Turn Off CSS

Disable your site's CSS in your browser. Can you still understand the structure and relationships? If headings don't look like headings without CSS, they're probably not real headings in the HTML.

Use a Screen Reader

Navigate your site with NVDA, JAWS, VoiceOver, or Orca. Screen readers announce element types and let you browse by headings, lists, form fields, etc. If these don't work as expected, your semantics are wrong.

Check the Accessibility Tree

Browser developer tools include an accessibility inspector that shows how the browser interprets your HTML for assistive technology. Use it to verify that relationships are properly conveyed.

Validate Your HTML

Use the W3C HTML validator to check for structural errors. Invalid HTML often indicates semantic problems that affect accessibility.

How CMSs Handle Semantic HTML

Drupal: Built on Semantic HTML

Drupal has a strong foundation in semantic HTML. With a good theme - whether it's the new Drupal Canvas, Olivero (the default theme), or other well-built themes - most of this semantic structure is handled for you:

  • Content types automatically use proper heading hierarchy
  • Form API generates proper labels and field associations
  • Views output structured lists with proper markup
  • Navigation menus use semantic list elements
  • Regions use proper landmark elements like <header>, <nav>, <main>, and <footer>

The key is choosing a theme that follows Drupal's best practices. Most modern Drupal themes handle semantic HTML correctly by default, though custom themes need proper attention during development.

WordPress: More Variable Quality

WordPress themes vary widely in their accessibility and semantic HTML quality. While WordPress has an "Accessibility Ready" tag in their theme directory, this only means the theme meets minimum standards set by the theme review team - not full WCAG AA compliance.

Common issues found even in popular WordPress themes include:

  • Missing or improper ARIA markup - especially on search forms and navigation menus
  • Inconsistent heading hierarchies - headings that skip levels or use wrong levels
  • Non-semantic navigation - menus built with divs instead of proper list elements
  • Improper button/link usage - divs with onclick handlers instead of proper buttons
  • Form label problems - labels that aren't properly associated with inputs

Page builders like Elementor and Divi add another layer of complexity. While they make design easy, they often generate non-semantic markup and provide limited options for fixing accessibility issues without diving into code. Some modules like carousels, accordions, and forms frequently have accessibility problems.

If you're using WordPress, carefully evaluate your theme's accessibility before committing to it. Look for themes that:

  • Are marked "Accessibility Ready" in the WordPress theme directory
  • Use semantic HTML5 elements
  • Have been tested with screen readers
  • Provide proper keyboard navigation
  • Include skip links and landmark regions

When building custom WordPress themes, start with a foundation like the Underscores starter theme, which provides clean semantic HTML as a base.

The Bottom Line

Info and Relationships is one of the most fundamental accessibility standards because it affects everything else. When you use semantic HTML correctly:

  • Screen readers work properly
  • Keyboard navigation makes sense
  • Browser reader modes work better
  • Search engines understand your content better
  • Your code is more maintainable

The good news? This is often the easiest accessibility fix. Change a <div> to a <button>. Use <h2> instead of styled spans. Add proper <label> elements to your forms. These small changes have huge impacts.

Before you style something to look like a heading, list, button, or form label, ask yourself: am I using the HTML element that conveys that meaning? If not, start there. Semantic HTML isn't a nice-to-have - it's the foundation of accessible web development.

Image
Accessibility Tree in Chrome devtools

Add new comment

The content of this field is kept private and will not be shown publicly.

Filtered HTML

  • Web page addresses and email addresses turn into links automatically.
  • Allowed HTML tags: <a href hreflang> <em> <strong> <blockquote cite> <cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h1> <h2 id> <h3 id> <h4 id> <h5 id> <p> <br> <img src alt height width>
  • Lines and paragraphs break automatically.