In plain English
When you look at a page, you instantly see its structure: this is a heading, that’s a list, these cells belong to that column, this box is a form field for “email.” You get all that from visual design.
A screen reader can’t see design; it can only read the code. So if your structure lives only in styling (big text, indentation, columns) and not in the markup, assistive tech has no idea it’s there. This rule says: code the structure, don’t just style it.
Who this is for
- Screen-reader users, who navigate by real headings, lists, and landmarks, and rely on labels to know what a form field is for.
- People using reader modes or custom stylesheets, where your visual layout is stripped away and only the markup’s structure remains.
What “good” looks like
Use the element that matches the meaning, not a styled generic box.
<!-- Good: a real heading and a real label -->
<h2>Shipping address</h2>
<label for="zip">ZIP code</label>
<input id="zip" name="zip" autocomplete="postal-code">
<!-- Bad: looks like a heading and label, but code says otherwise -->
<div class="big-bold">Shipping address</div>
<input name="zip" placeholder="ZIP code">
The placeholder disappears once you type, and it isn’t a label to a screen reader, so the second field effectively has no name.
Where stores get it wrong
Theme sections built from styled <div>s instead of headings, checkout fields
labelled only by placeholder text, and “tables” of specs laid out with columns
of text instead of real table markup. These show up constantly in a
self-check and on the
common failures list.