# Button labels cut off when people widen text spacing

Source: https://easeweb.dev/learn/text-spacing
Topics: Zoom, reflow and text spacing > Text spacing can be increased (WCAG 1.4.12)
The fix: Let every button grow when its label grows, and don't lock spacing with inline !important. Either let the label wrap inside a button with a minimum height, or let the row of buttons wrap so each button takes the width its label needs. Both pass; the first keeps the buttons side by side, the second keeps labels on one line wherever they fit.
Test with: text spacing
References: https://www.w3.org/WAI/WCAG22/Understanding/text-spacing.html https://www.w3.org/WAI/WCAG22/Techniques/failures/F104 https://www.w3.org/WAI/WCAG22/Techniques/css/C36 https://www.w3.org/WAI/WCAG22/Techniques/css/C35 https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap https://developer.mozilla.org/en-US/docs/Web/CSS/min-height

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

## What happens

A shop's product page puts a large photo on the left and the details in a narrow column beside it. In that column, two buttons sit side by side under the price: "Add to basket" and "Buy it now". At the shop's own spacing both labels fit with room to spare. Someone with dyslexia reads with an extension that widens the space between letters and words. Each label grows by about a fifth, but the buttons stay the same size. "Buy it now" still fits; "Add to basket" doesn't, and is cut short to "Add to bas…". On a narrower phone, both are cut. The size selector's tabs and the "Notify me" button further down the page fail the same way.

## Why it fails

The buttons share the row equally and are styled with `height: 44px` and `line-height: 44px` to centre the label. The label inside has `white-space: nowrap` to keep it on one line, and `overflow: hidden` with `text-overflow: ellipsis` in case it is ever too long. Success criterion 1.4.12 asks that nothing is lost when people set line height to 1.5 times the font size, space paragraphs by 2 times the font size, letters by 0.12 times and words by 0.16 times. At those values each label needs more width, but the button can't grow across because it shares a fixed row, can't wrap because of `nowrap`, and can't grow down because of its fixed height. So the browser cuts the label and adds an ellipsis.

## Who is affected

People who change text spacing set it once for every site, and many use a browser extension or reading mode that also changes the font, which lengthens labels again. Buttons are where a cut hurts most: "Add to bas…" can still be guessed, but "Delete acc…" and "Delete add…" can't be told apart.

## What automation and AI miss

axe checks one part of 1.4.12: its rule `avoid-inline-spacing` flags inline spacing marked `!important`, which stops a reader's stylesheet from taking effect. It doesn't apply the spacing and look for clipped labels, so the buttons above pass. A probe has to apply the four values, then compare each control's box with the text inside it. AI fixes tend to go wrong in one of three ways, each of which leaves part of the label unreadable:

- Deleting `overflow: hidden` alone: the label spills past the button's edge and runs into the next button.
- Shrinking the font when the label doesn't fit: the reader's spacing is kept, but the text gets smaller than they can read.
- Adding a `title` with the full label: it shows only on mouse hover, after a delay, and never on touch.

## Before: buttons with a fixed size and one line

```html
<div class="buy-row">
  <button type="submit" class="button"><span class="button-label">Add to basket</span></button>
  <button type="button" class="button button-secondary"><span class="button-label">Buy it now</span></button>
</div>
```

```css
.buy-row {
  display: flex;
  gap: 8px;
}
.button {
  flex: 1;
  height: 44px;
  line-height: 44px;
  padding: 0 16px;
}
.button-label {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
```

With the 1.4.12 spacing, each label is wider than its half of the row. The button can't grow in any direction, so the end of the label is hidden behind an ellipsis.

## After: let the label wrap

```css
.buy-row {
  display: flex;
  gap: 8px;
}
.button {
  flex: 1;
  min-height: 44px; /* not height */
  padding: 10px 16px;
  line-height: 1.3;
  /* and remove the .button-label rule: no nowrap, overflow or ellipsis */
}
```

At the shop's own spacing the buttons look as before: one line each, 44 pixels tall, with the label centred by padding instead of line height. With wider spacing, a label that no longer fits wraps onto a second line and the button grows taller to hold it. The buttons stay side by side and the HTML doesn't change.

## After: let the row wrap

```css
.buy-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.button {
  flex: 1 1 auto; /* as wide as the label needs, sharing what is left */
  min-height: 44px;
  padding: 10px 16px;
  line-height: 1.3;
  /* and remove the .button-label rule: no nowrap, overflow or ellipsis */
}
```

Each button takes the width its label needs and they share any space left over. When the two labels no longer fit side by side, the second button moves to a row of its own, and both stretch to the full width. The labels stay on one line wherever a full row is wide enough; only on a very narrow screen does a label wrap inside its button, and the minimum height lets it. The HTML doesn't change.

## Which option to use

Both options keep every label readable with the 1.4.12 spacing, and both meet the criterion. Letting the label wrap is the smaller change and keeps the buttons in the place the design gave them, but a two-line button label is a little harder to scan. Letting the row wrap keeps each label on one line, which reads better, but the buttons stack when space runs out, so the layout below them moves down. Choose label wrapping when the buttons have to stay side by side, such as in a toolbar or a table row; choose row wrapping where stacking is fine, which is true of most forms and product pages.

## Implementation decisions

**Find the other fixed controls.** Look for `height` with `line-height` in pixels, `white-space: nowrap` and `text-overflow: ellipsis` on anything that holds a label: tabs, pills, badges, nav links, dropdown items, table headers. Each needs `min-height` and padding instead. An ellipsis on a long product name in a list, with the full name on the product page, is a design choice; an ellipsis on a control's label is lost content.

**Centre with padding, not line height.** `line-height: 44px` centres one line and makes every wrapped line 44 pixels tall. Use padding, or `display: inline-flex` with `align-items: center`, so a second line sits close to the first.

**Leave spacing open to override.** People apply the 1.4.12 values with a user stylesheet or an extension. An inline `style="letter-spacing: 0 !important"`, often written by a page builder or a rich-text editor, beats their stylesheet, and that is a failure on its own (axe's `avoid-inline-spacing`). Move spacing into the stylesheet, and drop `!important` from line, letter and word spacing.

**Overlapping, not only clipping.** Text positioned absolutely, such as a "Sale" badge pinned to a product photo or a caption over a hero image, doesn't get cut off when spacing grows; it runs over its neighbours instead. Check that it still has room, or let it take its place in the flow.

**Icons and fixed widths.** A button with an icon and a label in a fixed `width` fails the same way. Let it size to its content, with a `min-width` if the design needs one.

**Third-party widgets.** Payment buttons, chat launchers and cookie banners often set their own heights. Test them with the spacing applied and report clipping to the vendor; the criterion applies to the whole page.

**Other scripts.** Japanese and other scripts without spaces between words gain little from word spacing, but letter spacing and line height still apply. Test every language the site ships in.

## Verify the fix

1. Apply the 1.4.12 values to the page with a text spacing bookmarklet or a user stylesheet: line height 1.5, paragraph spacing 2em, letter spacing 0.12em, word spacing 0.16em.
2. Read every button, tab and menu item, and check that each shows its whole label, with no ellipsis, nothing overlapping and nothing hidden behind another element.
3. Try the longest real labels, in every language, at the narrowest width the site supports.
4. Apply the spacing with a reading extension that also changes the font, and check again.
5. In the DOM, check that no inline style sets line, letter or word spacing with `!important`.

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the button component or theme changes.

## Limits

This is a starting pattern, not a guarantee for every application. 1.4.12 asks only that content survives the four values; it doesn't require a site to offer spacing controls of its own. Some content is exempt, such as text in images and captions burned into video. Class names in the snippets are placeholders. Test every template that has controls, not only the product page.
