Auto-Fit Column Width and Text Truncation
Permalink to "Auto-Fit Column Width and Text Truncation"Truncated cell text — “Lund & Co Indus…” — is one of the most common readability problems in data grids. Sighted users can sometimes hover for a tooltip or drag the column wider. Keyboard users cannot drag; magnifier users see even less; users with cognitive disabilities struggle to identify records by fragments. Auto-fit (sizing a column to its content), sensible minimums and wrapping options reduce truncation; accessible reveal techniques cover what remains.
This guide belongs to column resizing, reordering & freezing.
Spec reference
Permalink to "Spec reference"- SC 1.4.10 Reflow (AA) and SC 1.4.4 Resize Text (AA) — content remains available when zoomed; truncation at zoom must not hide information without access.
- SC 1.4.12 Text Spacing (AA) — increased spacing causes more truncation; full text must remain available.
- SC 2.1.1 (A) and SC 2.5.7 (AA) — width adjustment by drag needs keyboard and single-pointer alternatives (auto-fit and resize commands).
- SC 1.4.13 (AA) — tooltips revealing full text must be dismissible, hoverable and persistent.
When to use — and when not to
Permalink to "When to use — and when not to"Use auto-fit for columns whose content length varies widely (names, titles, descriptions) and users need to read them. Use wrapping (with a maximum of two or three lines) when horizontal space is tight. Keep truncation for secondary columns where full text is available elsewhere.
Do not auto-fit every column on every render; widths that jump as data changes disorient users. Fit on demand, or once on load, and persist.
The misapplication: fixed-width columns with text-overflow: ellipsis everywhere, full text only in title attributes.
Annotated code example
Permalink to "Annotated code example"// Auto-fit: measure the widest content in a column (header + visible cells) using canvas text metrics
function autoFit(colKey) {
const ctx = document.createElement('canvas').getContext('2d');
ctx.font = getComputedStyle(cellFor(colKey)).font;
const texts = [headerText(colKey), ...visibleCells(colKey).map(c => c.textContent)];
const width = Math.ceil(Math.max(...texts.map(t => ctx.measureText(t).width))) + paddingFor(colKey);
setColumnWidth(colKey, Math.min(width, 480)); // cap to avoid runaway widths
status.textContent = `${headerText(colKey)} column fitted to content, ${Math.round(width)} pixels`; // SC 4.1.3
saveWidth(colKey, width);
}
/* Wrapping with a clamp and an expand control */
.cell--wrap { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.cell--wrap[data-expanded="true"] { -webkit-line-clamp: unset; }
<td class="cell--wrap" id="c-88">Lund & Co Industrial Supplies — Northern Region Purchasing
<button type="button" class="more" aria-expanded="false" aria-controls="c-88">Show full name</button>
</td>
Keyboard & AT behaviour
Permalink to "Keyboard & AT behaviour"| Action | Key / control | Expected announcement |
|---|---|---|
| Auto-fit column | Column menu → Auto-fit, or Ctrl+Alt+F on header | “Customer column fitted to content” |
| Auto-fit all | Toolbar command | “All columns fitted” |
| Expand clamped cell | Enter on “Show full name” | “expanded”; full text readable |
| Truncated cell focus | Arrow onto cell | Full text read (DOM keeps it) |
Integration context
Permalink to "Integration context"Resizing by keyboard is covered in keyboard accessible column resizing; column menus in column header menus in data grids. Tooltip techniques for remaining truncation are in accessible tooltips for truncated cell text. Wide tables at zoom are discussed in meeting reflow 1.4.10 with wide tables.
Gotchas
Permalink to "Gotchas"Virtualized columns. Auto-fit measures only rendered cells; measure a sample of data instead or fit on scroll end.
Fonts loading. Measure after web fonts load (document.fonts.ready), or widths will be wrong.
Persisted widths at different zoom levels. Store widths in CSS pixels; they scale with zoom, which is usually right.
Worked example
Permalink to "Worked example"A procurement grid used 140-pixel columns for supplier names, truncating most of them. Keyboard users could not widen columns and relied on opening each record. The team set content-based minimums, added “Auto-fit column” to header menus and a toolbar “Fit all columns” command, offered a “Wrap long text” density option and kept full text in the DOM with focus tooltips for the remaining truncated cells. Users stopped opening records just to read supplier names.
Common mistakes
Permalink to "Common mistakes"- Pixel widths chosen for the design mock’s data.
- Full text only in title attributes.
- Auto-fitting on every data change.
- Drag-only resizing.
Testing checklist
Permalink to "Testing checklist"Design system notes
Permalink to "Design system notes"Column definitions should include minWidth: 'content', overflow: 'wrap' | 'clamp' | 'truncate' and an auto-fit command in the column menu by default.
Step-by-step implementation
Permalink to "Step-by-step implementation"- Choose what may truncate. Identifiers, amounts and dates should never truncate; long free-text fields such as descriptions may. Mark truncating columns in the column definition, not ad hoc in CSS.
- Truncate visually, not in the DOM. Use
text-overflow: ellipsiswithoverflow: hiddenandwhite-space: nowrap. The full text stays in the DOM, so screen readers read all of it and Find in page still matches. - Reveal the full value on demand. Provide a way for sighted keyboard and pointer users to see the whole value: a tooltip on focus and hover that is dismissible with Escape and hoverable, or an expand control in the cell. A
titleattribute alone does not satisfy keyboard users. - Offer auto-fit as a command. Double-clicking a resize handle is a pointer-only shortcut; add “Autosize column” to the column menu and a keyboard shortcut, and announce the new width.
- Respect text spacing. Test with the SC 1.4.12 text spacing bookmarklet; truncated cells must still let users get to the full text when letter and word spacing increase.
Edge cases
Permalink to "Edge cases"- Auto-fit on huge data sets. Measuring every row is expensive in virtualized grids; measure the rendered rows plus the header, and say in documentation that the result is approximate.
- Zoom. At 200% zoom, more cells truncate. Check that the reveal mechanism still works and does not cover the focused cell.
- Translated content. German and Finnish strings are often much longer; truncate the description column, not the button labels.
Testing it with a screen reader
Permalink to "Testing it with a screen reader"Open the grid with NVDA and Firefox and move into a column that truncates. Listen for the full value: because the text is only clipped visually, NVDA should read the complete description, not the ellipsis. Then tab to the cell’s reveal control or focus the cell and confirm that the tooltip or expanded view appears for sighted keyboard users and can be dismissed with Escape without moving focus. Next, open the column menu, choose “Autosize column” and check that a status message reports the change. Repeat in VoiceOver with Safari. Finally, use a screen magnifier at 300% and confirm that the revealed text stays near the focused cell rather than appearing off-screen, where magnifier users would never find it.
FAQ
Permalink to "FAQ"Is truncation a WCAG failure?
Not by itself, if full text is available. Truncation without access to full text can fail 1.3.1 and usability badly.
Should auto-fit consider all rows?
Ideally a representative sample; measuring thousands of rows is slow.
How do screen readers handle truncated cells?
They read the full DOM text; the problem is mainly visual, but focus tooltips help sighted keyboard users.
Should widths persist?
Yes, per user and per grid.
What about RTL text?
Measure with the correct direction and font; ellipses appear on the left in RTL.
Can I auto-fit headers?
Include header text in measurements so headers are not truncated either.
Related
Permalink to "Related"- Keyboard accessible column resizing — manual widths
- Truncated cell tooltips — fallback reveal
- Text spacing override testing — truncation under spacing