Lesson 02·Unit 2 · Three failures you can see·Translation length variance & layout flex·Lv 101·~6 min
Text expansion stress test
Translated copy is rarely the same length as the source. German runs 30–50% longer, Russian 20–40% longer, Finnish builds compounds that don't fit in a button. Designs built for English silently break, usually at the smallest breakpoint.
By the end
- ·Budget headroom by source length: up to 10 characters, plan for 200–300% growth, and less as strings get longer.
- ·Name the languages that shrink English text, and why your layout has to survive shrinking as well as swelling.
- ·Defend a layout with flexible containers and real strings, rather than truncating, capping length, or shrinking the font.
The problem
The default English string says "Sign in". The German translation is "Anmelden" (fine), the Finnish is "Kirjaudu sisään" (twice as long), and the Russian is "Войти в систему" (also longer, plus Cyrillic widths). A button that fits one breaks the others, and your design system's paddings, icon spacings, and badge widths break with it. Designers who don't see the expanded copy at design time ship layouts that look fine in English and ragged everywhere else.
How it works
Why translations do not fit
Translations change length for structural reasons, not careless ones. German fuses ideas into compounds where English uses short phrases. Russian and Finnish carry grammar inside longer word forms, and French spends characters on articles and spacing. The effect is worst where you have the least room. The shorter the source string, the larger the proportional growth, because a four-letter label has nowhere to hide the grammar another language needs. That is the basis of the IBM guidance W3C republishes: up to 10 source characters, plan for 200–300% growth.
The effect also runs the other way: Chinese and Japanese often say an English sentence in a fraction of the width, so the same component must look right both fuller and emptier than the mockup. The translator controls none of this. The layout decides whether length becomes a bug. Fixed widths truncate. Flexible containers with sensible minimums, wrapping room, and real-string testing absorb the change. "It fit in English" is the one test every UI passes.
How it works
The counter in the editor is not the limit in the box
Sooner or later someone hands a translator a character budget: keep this button under 16. That budget is only useful if everyone agrees what a character is, and three common answers disagree. str.length in JavaScript counts UTF-16 code units. Spreading the string counts code points. Intl.Segmenter at grapheme granularity counts what a reader would call characters. For plain ASCII all three match. That is why the disagreement survives review and reaches production.
They diverge on the text localization deals in. Take a thumbs-up with a skin tone: one grapheme, two code points, four UTF-16 units. Enforce your budget with length and you charge that emoji four times, rejecting a string that fits on screen. Or take an accented letter typed in decomposed form. It counts one higher than the same letter precomposed, so the same word passes or fails depending on which keyboard your user typed it on.
The larger problem is that none of the three is what the UI enforces. A button truncates at a pixel width, and pixel width has no fixed relationship to any character count: six Japanese characters can render wider than eleven Latin ones. A character budget is a proxy. When the layout is the real constraint, measure the layout, and give translators the box rather than a number.
See it yourself
Try these, in order
Each step triggers a specific failure you should recognize on sight.
- 1Keep the “CTA button” scenario and drag the container width down until German (“In den Warenkorb”) breaks. Note the width where en-US still fits comfortably. That gap is where the bug appears. The % badges show each locale's swell against English.
- 2Find Chinese (加入购物车) and Japanese in the grid. CJK often contracts: the badge shows negative expansion. Now your button has to look right both fuller and emptier than designed.
- 3Switch the scenario to “Notification card”. Longer source strings swell by a smaller percentage: the 200–300% figure is a short-string problem. Compare the badges against the button scenario.
- 4Pick the narrowest width where every locale still renders acceptably. That is the component's minimum content width to hand your design system: a measured number instead of a guess.
Add to cart
In den Warenkorb
Ajouter au panier
Añadir al carrito
Adicionar ao carrinho
Aggiungi al carrello
Добавить в корзину
Dodaj do koszyka
Lisää ostoskoriin
加入购物车
カートに追加
أضف إلى السلة
One string, three different sizes
Code points, UTF-8 bytes, and rendered pixels are three separate numbers. Watch them disagree: Mandarin usually has the fewest characters, is among the widest in pixels, and weighs the most bytes.
| Locale | Title | chars | UTF-8 bytes | px | vs. en-US |
|---|---|---|---|---|---|
| en-US | Add to cart | 11 | 11 | — | 0% |
| de-DE | In den Warenkorb | 16 | 16 | — | +45% |
| fr-FR | Ajouter au panier | 17 | 17 | — | +55% |
| es-ES | Añadir al carrito | 17 | 18 | — | +55% |
| pt-BR | Adicionar ao carrinho | 21 | 21 | — | +91% |
| it-IT | Aggiungi al carrello | 20 | 20 | — | +82% |
| ru-RU | Добавить в корзину | 18 | 34 | — | +64% |
| pl-PL | Dodaj do koszyka | 16 | 16 | — | +45% |
| fi-FI | Lisää ostoskoriin | 17 | 19 | — | +55% |
| zh-CN | 加入购物车 | 5 | 15 | — | -55% |
| ja-JP | カートに追加 | 6 | 18 | — | -45% |
| ar-SA | أضف إلى السلة | 13 | 24 | — | +18% |
Once measured, the "vs. en-US" column compares rendered pixel width. Of the three numbers, only pixels decide whether a translation overflows its box.
Writing to a limit
A translator receives a character budget and a box. The counter in the editor, the number in the spec, and the width the UI enforces are three different measurements. They disagree exactly when it matters.
Graphemes
16
what the reader sees
Code points
16
[...str].length
UTF-16 units
16
.length, what most tools count
Pixels
0
box is 120px
In the real container
Inside both limits. Try the Japanese preset: six characters, and watch the pixel counter.
The three counts diverge only on non-ASCII text. An emoji with a skin tone is one grapheme, two code points, and four UTF-16 units. A budget expressed in .length silently charges it four times.
The "30% rule" is a lie
Localization training material repeats the line "translations expand by ~30%." For short UI strings (1–3 words) the real spread is −50% (CJK) to +70% (Portuguese, Russian, German). Character count is also the wrong budget: a Mandarin label with the fewest characters can render the widest and weigh the most bytes. Size your boxes in pixels, not characters. Give icon-only labels a generous min-width and allow subtitles to wrap to two lines. Avoid right-edge absolute positioning for CTAs: it lands on the wrong side in Arabic and Hebrew.
If you remember one thing
Budget +200–300% width for short strings and design layouts that flex. If the German fits, most things fit.
What to do about it
- Design rule: assume +50% width for all UI strings, and +100% for short labels (buttons, badges, menu items). Verify by pseudo-localizing your design files (Figma plugins exist) or running the live UI through the pseudoloc demo.
- Avoid fixed-width text containers. Use
min-width+ flexiblemax-widthso buttons grow with their content instead of truncating. - For text inside icons (status badges, avatars), use a tooltip with the full string and a truncated label. Never use icon-only buttons in regions where the icon's meaning isn't culturally universal.
- Build a "longest string" test that runs in CI against the real translation memory; the source-language bound is a poor substitute.
Use this with
Stakeholders
Moments
- ·Design review for any UI change
- ·Component library audit
- ·Pre-launch QA for German / Russian / Finnish
See it in a market: Germany: long compound nouns, +50% width reserved →
Field note
The industry rule of thumb (IBM's classic table, republished by W3C): the shorter the English source, the worse the swell. Up to 10 characters, plan for 200–300% expansion. Buttons, tabs, and badges are where teams hardcode widths, and also where translations are longest relative to source.
Quick check
3 questions · pass at 2+
Question 1/3
Per the W3C/IBM guidance, how much expansion should you plan for on a short English string (≤10 characters)?
Question 2/3
Which target languages commonly make English UI text shorter?
Question 3/3
Which layout defense against expansion holds up?