Translated text is clipped, cut off, or overlapping in the UI
A button reads Confirm comfortably in the source language, but the translated label is longer and the last two characters disappear behind the button's edge. Or a tooltip's second line overlaps the line below it. The English build looked fine in every review; the bug only exists once the string is replaced with a translation.
This is not a translation quality problem — the words are correct. It is a layout that was sized for one language's typical length and never tested against any other. The question is not how to make this one string shorter in isolation; it is which of three fixes — shortening the text, changing the layout, or allowing the text to wrap — actually addresses the cause in front of you.
Find the actual constraint before picking a fix
Three different layout decisions all produce the same visible symptom, so check which one you are dealing with before touching anything.
- A fixed-width or fixed-height container with no wrap and no overflow handling — text simply runs past the edge or gets clipped by CSS overflow rules
- A character-count limit enforced somewhere in the pipeline, but measured in the wrong unit for the target language (see below)
- Font metrics: the translated script renders taller, wider, or with more line spacing than the source font at the same point size, even at an identical character count
Why character limits measure the wrong thing
A limit written as a maximum of 20 characters behaves very differently per language even when the words mean the same thing. Languages with longer average word length (German compound nouns are the classic case) routinely need more characters than English to say the same thing. Meanwhile CJK languages often need far fewer characters for the same meaning, but each character occupies more visual width — a 10-character Japanese string can be visually wider than a 20-character English one.
So a single numeric character limit shared across all languages either clips languages that need more characters, or wastes space and under-uses the layout for languages that need fewer but wider ones. The unit that actually matters for layout is rendered pixel width in the target font, not character count — character count is only a cheap, imperfect proxy for it.
// A limit that ignores width will pass strings that don't fit const maxLength = 20; "设置" .length // 2 — passes easily, renders fine "Application Settings".length // 21 — fails the count, but may render fine too // character count and rendered width are not the same axis
Deciding between shorten, relayout, and wrap
Shortening the text is the right fix when the string is a label in a fixed, small control — a button, a tab, a badge — where wrapping or resizing would break the visual design of a component used everywhere. Ask the translator for a shorter alternative that fits the same meaning; this is a translation task, not an engineering one.
Changing the layout is the right fix when the container's size was arbitrary rather than load-bearing — a card, a panel, a modal that can simply be wider or taller without breaking anything around it. This is usually the best fix when it's available, because it removes the constraint instead of working around it.
Allowing wrap is the right fix for any text that is not a single-line control label — descriptions, body text, item names in a list. A single line that must never wrap is a much stricter requirement than most UI actually needs, and it is worth checking whether that constraint was ever intentional or just inherited from the source-language design.
Setting a length budget that can be checked mechanically
Once you know the real constraint is rendered width, express the budget in a form that can be verified without a human eyeballing every screenshot: either a maximum pixel width per string measured against the actual target font, or — as a cheaper approximation — a per-language character multiplier applied to the source string's length, since expansion ratios differ predictably by language pair rather than being random.
// Cheap approximation: language-specific expansion factor
const expansionFactor = { de: 1.3, ja: 0.6, ko: 0.7, "zh-CN": 0.5 };
const budget = Math.ceil(sourceLength * (expansionFactor[targetLang] ?? 1.2));Prevention
Design fixed-width controls around the longest language you actually ship, not the source language — German and Finnish are reliable stress tests for expansion, Japanese and Korean for visual width per character. Whichever fix you land on for a given string, record the constraint (max width, or wrap allowed) next to the string's key so the next translator or the next UI change respects it instead of rediscovering the same clipping bug.