Keep Wide Tables Scrollable Without Breaking Page Reflow
A semantic comparison table needs two-dimensional space, but allowing its 640-pixel width to escape the article makes unrelated text scroll horizontally too.
overflow-x: visible- Viewport / page
- --
- Table region
- --
- Page overflow
- --
overflow-x: auto- Viewport / page
- --
- Table region
- --
- Page overflow
- --
Three-browser evidence verified. Live values come from your current browser. The formal matrix records the controlled browser runs and fixture revision used for the published conclusion.
Observed failure
The table exception expands to the whole page
The 640-pixel table needs room to preserve its column relationships, but its wrapper leaves inline overflow visible. The table then increases the document scroll width and forces surrounding prose to move sideways.
Minimal code diff
Put two-dimensional scrolling on the table region
Keep the semantic table and its minimum useful width, while constraining a labeled, keyboard-focusable wrapper with `overflow-x: auto`.
Before
.table-region {
overflow-x: visible;
}
.comparison { min-width: 640px; }After
.table-region {
max-inline-size: 100%;
overflow-x: auto;
}
.comparison { min-width: 640px; }Root cause
Tabular data can require a two-dimensional relationship between row headers, column headers, and cells. That does not mean the entire document needs two-dimensional scrolling. With visible overflow, the table’s minimum width participates in the page’s scrollable area and prevents unrelated content from reflowing within the viewport.
The fixed example retains native table, caption, th, and td elements. Only the table region becomes horizontally scrollable, so the structural relationships remain programmatically available while the surrounding article stays within the page.
Check geometry and relationships together
At a narrow viewport, compare the document and table-region scroll widths. The intended result is zero page overflow and positive local overflow only inside the labeled wrapper. Reach that wrapper with the keyboard, scroll to the last column, and confirm that the focus indicator and caption remain visible. A region that can scroll only by touch or pointer leaves keyboard users without equivalent access.
Use the browser accessibility tree or a screen-reader table command to confirm that the native caption and row and column headers remain associated with their cells. Rebuilding the table as unrelated mobile cards may remove the horizontal scrollbar, but it can also discard the comparison relationships that make the data useful.
When this fix is not enough
A scroll wrapper cannot repair an overly complex table or missing header associations. Consider whether columns can be removed, grouped, or offered in a task-specific alternate view. For more complex multi-level headers, scope alone may not express every association and explicit id and headers values may be needed.
Regression condition
At 320 and 375 CSS pixels, the failing table must produce positive page-level overflow. The fixed page must have zero page overflow, while its labeled table region retains positive local horizontal overflow, accepts keyboard focus, and preserves semantic row and column headers.
Primary references
Sources checked for this case
- Understanding Success Criterion 1.4.10: Reflow - W3C Web Accessibility Initiative, checked 2026-08-04
- Understanding Success Criterion 1.3.1: Info and Relationships - W3C Web Accessibility Initiative, checked 2026-08-04
Formal evidence
Browser and viewport matrix
Cells show failing / fixed page overflow in CSS pixels.
| Browser | 320 | 375 | 768 | 1024 | 1440 |
|---|---|---|---|---|---|
| Chromium | +348 / +0 | +293 / +0 | +0 / +0 | +0 / +0 | +0 / +0 |
| Firefox | +348 / +0 | +293 / +0 | +0 / +0 | +0 / +0 | +0 / +0 |
| WebKit | +348 / +0 | +293 / +0 | +0 / +0 | +0 / +0 | +0 / +0 |
18/18 recorded assertions passed
chromium-failing-overflow-320348pxchromium-fixed-overflow-3200pxchromium-fixed-local-scroll-320376pxchromium-failing-overflow-375293pxchromium-fixed-overflow-3750pxchromium-fixed-local-scroll-375321pxfirefox-failing-overflow-320348pxfirefox-fixed-overflow-3200pxfirefox-fixed-local-scroll-320376pxfirefox-failing-overflow-375293pxfirefox-fixed-overflow-3750pxfirefox-fixed-local-scroll-375321pxwebkit-failing-overflow-320348pxwebkit-fixed-overflow-3200pxwebkit-fixed-local-scroll-320376pxwebkit-failing-overflow-375293pxwebkit-fixed-overflow-3750pxwebkit-fixed-local-scroll-375321px
Run 2026-08-04T11-36-57-234Z. chromium 149.0.7827.201, firefox 153.0, webkit 26.5. Open raw manifest