WCAG 1.3.1 — Info and Relationships
Information conveyed by visual structure — headings, lists, tables, form labels, groupings — must also be available to assistive technology programmatically. The shape of the page has to match the shape of the markup.
What this requires
Whatever a sighted user can infer from layout — that one thing is a heading and another is body text, that these three items form a list, that this label belongs to that input, that these cells form a row — must be expressed in the underlying markup, not just the visual styles. If you remove all CSS and the structure still reads correctly, you are close to passing. If everything collapses into a single undifferentiated paragraph, you are not.
How AI coding tools fail this
The single most common failure: AI assistants reach for <div> and
font sizing instead of semantic elements. A "heading" that is just a
larger <div> has no role to expose, no place in the page outline, and
no way for a screen-reader user to navigate to it. The pattern shows up
in marketing pages, dashboards, and component libraries alike.
The second pattern: form fields without programmatic labels. The input
visually sits next to text that looks like a label, but the markup
never associates them — no <label htmlFor>, no aria-labelledby, no
aria-label. The placeholder fills the visual gap, then disappears the
moment the user types.
The third: lists rendered as a sequence of <div> siblings. The visual
bullets are CSS pseudo-elements; the screen reader hears "five items"
nowhere, only five disconnected paragraphs.
Edge cases
- Tables for tabular data need
<th>,scope, and<caption>. Tables used purely for layout (rare in modern CSS) needrole="presentation". - Groups of related fields (a radio group, address fields, a date
picker) need a
<fieldset>with a<legend>to carry the group label. - Decorative structure — a divider, a flourish, a background icon —
should have
role="presentation"oraria-hidden="true"so the screen reader skips it. - Visually-hidden labels are allowed and often necessary. Use the
sr-onlyTailwind utility (or equivalent) rather thandisplay:none, which removes the element from the accessibility tree.
How Jeikin handles this
Jeikin's CLI scanner flags <input> elements that lack any of
aria-label, aria-labelledby, or an associated <label> element,
and maps each finding to WCAG 1.3.1. The MCP server returns the
correct semantic pattern for the widget type — heading versus styled
div, fieldset/legend for grouped fields, label/htmlFor for form
controls — when the AI assistant is about to ship the wrong one.
The dashboard tracks each finding through resolution with a timestamped audit trail.