Skip to main content

Notes

Making Size Charts and Spec Tables Accessible for E-Commerce

Quietramp ·

Making Size Charts and Spec Tables Accessible for E-Commerce

Nearly every apparel and footwear listing has one: a size chart mapping size labels to measurements — chest, waist, inseam, or shoe length in two unit systems. It’s one of the most consulted pieces of content on a product page, and one of the most consistently inaccessible, because of how it’s usually built: as a single flattened image, or as an HTML table with no header markup, so a screen reader can read the numbers but not say which row or column any belong to.

Quick answer: an accessible size chart needs three things — the data has to exist as real text, not baked into an image (WCAG 1.1.1 Non-text Content); it has to be marked up as an actual <table> with <th> header cells and scope (or headers/id for multi-level headers) so a screen reader can announce “Size M, Chest, 40 inches” instead of just reading four numbers in a row (WCAG 1.3.1 Info and Relationships); and it has to reflow on small screens without losing that row/column association, which for a genuine data table means preserving the table markup rather than restacking it into unlabeled text blocks (WCAG 1.4.10 Reflow). None of this requires new content — the numbers already exist in whatever system generated the chart. It requires different markup.

This article covers technical accessibility practice, not legal advice — it explains what WCAG 2.1 AA requires for tabular content and how to meet it, not whether a specific site carries legal risk.

Why a size chart image fails, specifically

A size chart built as a single image — a common shortcut, since it’s easy to design once and drop onto every product page in a category — fails for a reason more specific than “missing alt text.” Even a well-written alt attribute can’t fix it, because alt text is a short, single string, and a size chart is inherently two-dimensional data: a chest measurement or inseam length, meaningful only in relation to its row and column.

The W3C’s own guidance on WCAG 1.1.1 Non-text Content addresses this directly under what it calls Situation B: content “if a short description (alt text) can not serve the same purpose and present the same information as the non-text content.” Its own worked example is a data chart — the short alternative should give “a high-level summary,” and “where possible and practical, the actual data is provided in a table.” A size chart is that example: alt="Size chart" can’t reproduce eighteen data points a shopper needs to cross-reference, but a real table can.

The fix isn’t better alt text on the image — it’s not using an image for this content at all.

Mark up headers so a screen reader can announce them correctly

A <table> with plain <td> cells and no <th> elements is only marginally better than an image: a screen reader will read the numbers in sequence without stating which row or column each belongs to — “40, 32, 41, 34, 42, 36,” with no way to tell that the first pair is Small and the second Medium.

WCAG 1.3.1 Info and Relationships (A) requires that relationships conveyed visually — here, “this number belongs to this row and this column” — be programmatically determinable, not just visible. The standard’s own example describes this directly: “items that share a common characteristic are organized into a table where the relationship of cells sharing the same row or column and the relationship of each cell to its row and/or column header are necessary for understanding,” illustrated with a bus-schedule table whose headers “can be programmatically determined.”

The W3C WAI Tables Tutorial lays out the concrete technique: header cells get marked up with <th> instead of <td>, and for a table with headers on two sides (size labels down the left, measurement types across the top — the standard shape of a size chart), each <th> gets a scope attribute set to col or row to state which direction it applies to.

<table>
  <caption>Women's dress sizing (inches)</caption>
  <tr>
    <th scope="col">Size</th>
    <th scope="col">Bust</th>
    <th scope="col">Waist</th>
    <th scope="col">Hip</th>
  </tr>
  <tr>
    <th scope="row">Small</th>
    <td>34–35</td>
    <td>27–28</td>
    <td>37–38</td>
  </tr>
  <tr>
    <th scope="row">Medium</th>
    <td>36–37</td>
    <td>29–30</td>
    <td>39–40</td>
  </tr>
</table>

With this markup, a screen reader moving through the “36–37” cell announces it together with both its row header (“Medium”) and column header (“Bust”) — the exact relationship a sighted shopper gets for free from the grid layout.

Handle irregular headers with headers and id

Some spec tables are more complex than a simple grid — a shoe-size chart that groups US, UK, and EU sizing under a shared “Size” header spanning multiple columns, for instance. When headers span multiple rows or columns and scope alone can’t express the relationship, the WAI tables tutorial’s guidance for irregular tables is to associate each data cell explicitly with its header cells: give each header an id, and list the relevant header ids in a headers attribute on each data cell, rather than relying on scope to infer the association from position. This is only necessary for genuinely multi-level or spanning headers — a straightforward one-header-per-axis chart, like the example above, doesn’t need it.

Don’t lose the table when the layout goes responsive

Wide spec tables are a common mobile-layout problem, and a frequent shortcut is to break the table apart into stacked <div>s below a certain screen width — a heading, then a list of label-value pairs restyled to look like rows. This usually drops the real <th>/<td> structure entirely, which quietly undoes the header-association work above: it still reads fine to a sighted user scrolling through stacked rows, but a screen reader is back to unlabeled values.

WCAG 1.4.10 Reflow (AA) carves out a specific exception here, running the opposite direction from most mobile-accessibility advice: content generally can’t require scrolling in two dimensions at a 320px viewport, but the standard states plainly that it “has exceptions for data tables and grids from needing to display without scrolling in the direction of text” — because a genuine data table has “a two-dimensional relationship between column and row headers and their data cells” that stacking would destroy. In practice: it’s fine, and often correct, for a wide size chart to stay a real horizontally-scrollable table on a narrow screen rather than get restructured into stacked divs, as long as the scroll region is reachable and operable by keyboard. What the exception does not cover is everything around the table — a heading or unit-toggle control tied to the chart still has to reflow normally within 320px, per the same Understanding doc’s clarification that the exception “only applies to that section.”

Give unit-toggle buttons a real accessible state

Most size charts pair with an inches/centimeters toggle. If that’s a custom-built control rather than two separate links, it needs to expose its current state to assistive technology, not just change appearance. The WAI-ARIA APG Button pattern covers two-state toggle buttons directly: set aria-pressed="true" or "false" and keep it in sync with the visible state. The pattern also flags a detail that’s easy to get backwards — “it is critical the label on a toggle does not change when its state changes,” illustrated with a mute button that keeps reading “Mute” (with aria-pressed reflecting on/off) rather than relabeling itself “Unmute.” Applied here: a “cm” button shouldn’t relabel to “in” after being pressed — either keep a stable label and toggle aria-pressed, or use two separate controls with a clear selected state.

Where to start

In order of effort: if a size chart exists only as an image, get the same numbers into a real <table> — a content and markup change, not a redesign, since the visual design can stay identical. From there, add scope="col"/scope="row" to header cells (a template change touching every product page at once), and confirm the mobile version is still a <table> under the hood rather than restyled divs that dropped the header structure.

FAQ

Is a size chart image with detailed alt text good enough? Not for a genuine multi-row, multi-column chart. WCAG 1.1.1’s own guidance says a short text alternative works only when it “can serve the same purpose and present the same information” as the original — for tabular data with more than a few values, that’s what a real table is for, not a longer alt string.

Do I need headers/id on every size chart, or is scope enough? scope="col"/scope="row" is sufficient for a standard single-header-per-axis table — the shape most size charts take. headers/id is only needed when headers span multiple rows or columns and scope can’t unambiguously express the relationship.

Is it okay for a size chart to require horizontal scrolling on mobile? Yes, for the table itself — WCAG 1.4.10 Reflow explicitly exempts data tables and grids from the general two-dimensional-scrolling restriction, since collapsing a genuine table into stacked text usually destroys the header/data relationship it depends on. Everything around the table (headings, unit toggles, surrounding page content) still needs to reflow normally.

Get a full audit of your product page markup

This covers one specific, common pattern — a full Quietramp audit checks your whole site against WCAG 2.1 AA, verified by a person operating it with a keyboard and screen reader, not just an automated scan (which will typically flag a size-chart image as a missing-alt-text error and stop there, without catching a structured-but-unlabeled table on the same page). See a real sample report, or check pricing — $890 one-time, $99/month for ongoing re-checks after fixes ship.


This is educational content about technical accessibility standards, not legal advice. Meeting WCAG 2.1 AA does not guarantee legal compliance with the ADA or any other law, and nothing here should be read as a compliance guarantee. Consult qualified counsel for legal risk questions.

This article was drafted with AI assistance and reviewed by a person for accuracy before publication.

← Back to Notes