Every string in this scene is a real translation of the English source "Add to Cart", rendered with the browser's own canvas.measureText() — the same primitive every layout engine uses to lay out text. The needed pixel width is:
need(lang) = measureText(text(lang), font) + padding
overflow(lang) ⇔ need(lang) > budget (budget = container width slider)
Character count is a poor predictor of pixel width across scripts — German and Dutch compound words run 30-80% longer than English at the same font size, while Chinese and Korean often use fewer characters that are each wider (full-width glyphs), landing close to English width. The only reliable check is measuring the rendered width in the target font, not counting characters.
Three strategies teams actually ship for a string that doesn't fit a fixed-width control:
- Overflow — text renders past the button's edge and collides with neighbours. Cheap, but a visible layout bug (the box literally widens past the dashed budget line here).
- Truncate + ellipsis — binary-search the longest prefix that fits budget − padding, append "…". Never breaks layout, but can delete meaning (e.g. a price or a negation word).
- Auto-shrink — reduce font size in 0.5px steps (down to a floor of ~55% of the base size) until it fits; falls back to truncation only if the floor still doesn't fit. This is iOS's
adjustsFontSizeToFitWidth / Android's autoSizeText.
Pseudo-localize applies a real QA technique: every string is padded ~30% longer and dressed with accented look-alike glyphs (Ȧȧ, Ẽẽ, Ĩĩ…) so a build can be screenshotted and checked for overflow risk before real translations exist — teams budget UI width for the worst real language, not the English original.
The lower panel is a live bar chart of each language's expansion ratio vs the English original at the current font size — click any button or bar to pin its exact numbers in the readout above.