Styling that impersonates structure drops the semantics
Aliases: fake semantics · presentational markup · CSS-as-structure
What it is
Bigger bolder type as a section, a prefixed dot as an item, ruled lines as a table, blank lines as a paragraph break — the picture has structure; the tree is flat. Presentational impersonation drops the roles assistive technology needs: the reader sees a stream of un-roled text nodes, with nowhere to jump, nowhere to move by item, nowhere to move by cell.
Heading-jump and list/table semantics are the two most common crime scenes. This leaf is the shared mechanism: if visual structure lives only in CSS, the semantic channel is empty.
Why it happens
Human vision reads hierarchy from contrast, alignment, numbering, indent. Assistive technology does not take that path; it asks each node for a role. font-size, left margin, a bullet in a pseudo-element, a border grid will fool the eye; the answer to “what role?” is still “generic container” or “a paragraph.” Two interfaces result: for the eye, sections, groups, tables; for the ear, an unmarked plain.
The loss is silent. The page throws no error, and automated checks often pass (contrast is there, focus is there) until someone summons a heading list or tries to walk a table by cell and discovers the structure never existed. Patching with the wrong role — wrapping the page as one table, marking a button as a heading — is worse than absence, because a fake role starts the wrong operation expectations.
Studying it
Ship the same content in a “style only” build and a real-semantics build. Screen-reader users do structure-dependent tasks: jump to a section, say how many items are in a list, read a cell relative to its headers. Dependent: success, whether they conclude the page has no sections, role counts in the element list.
Stripping CSS is the harsh control: real structure remains, impersonation vanishes. An accessibility-tree snapshot can quantify it: visual groups versus nodes that carry a structural role. The gap is the layer style stole.
Where it stops holding
Pure decoration (rules, textures, card radii) was never structure and should not have a role; marking those as headings or tables is the error. Exploring hierarchy with style in a mock is legitimate; delivery has to write the settled hierarchy as semantics. Some component libraries inject roles at runtime onto unsemantic containers — judge the tree after injection, not the source tags — but when injection fails, the failure is identical to “style only.”
Applying it
- Anything you would call, in review, “a section / a group of items / a table / a quotation” needs a matching role at delivery, not merely a lookalike style.
- Write semantics first, style second. If removing styles collapses the hierarchy to a sheet, the structure is not in the tree yet.
- Do not “fix” impersonation with the wrong role; absence is easier to repair than a false role.
- How to check: listen unstyled and styled. Structure operations (heading jump, list items, table headers) should work in both. Then read the accessibility tree: each visual group should point at a structural role. A group that points at nothing is style performing structure.