English is a compact language and designing in it first is a trap. "Down payment" becomes "aanbetaling"; "Total interest" becomes "Gesamtzinsen"; a label that fit neatly in its box now wraps, truncates, or pushes the input off the edge of a 375-pixel screen. German runs roughly 30% longer than English across a page of running text, and Dutch is close behind.
That average is the least useful number in the whole problem, because layouts do not break on averages. They break on the longest single label, and short labels are where the expansion is worst. "Undo" is four characters and "Rückgängig" is ten. "Delete" is six and the Dutch "Verwijderen" is eleven. "Speed limit" is eleven and "Geschwindigkeitsbegrenzung" is twenty-six. The rule translators work to: the shorter the English string, the larger the percentage it grows: is precisely backwards from the assumption a designer makes when choosing a column width from the English.
The problem is the shape, not the length
Look again at the two examples in the first paragraph and something odd shows up. "Aanbetaling" is eleven characters and "down payment" is twelve. "Gesamtzinsen" is shorter than "total interest". Both translations are shorter than the English, and both are harder to lay out, because Dutch and German build compounds where English uses two words.
A browser breaks a line at a space. "Down payment" has one, so in a narrow column it becomes two lines and the layout survives intact. "Gesamtzinsen" has none. It is a single unbreakable token, and a token wider than its container does one of three things depending entirely on your CSS: it overflows visibly, it gets clipped, or it forces the whole row wider and pushes something else off the screen.
The third is the one that catches people, and it has a specific and unobvious cause. A flex item defaults to min-width: auto, which means it refuses to shrink below the width of its own content. One long compound in one label and the entire row grows to accommodate it, taking the input field with it. Setting min-width: 0 on the flex child is the fix, and it is the single line of CSS that has rescued this layout more often than any other.
What actually survives
Four habits, in order of how much trouble each one prevents.
No fixed-width text containers, anywhere. Labels size to their content and the layout flexes around them; nothing is measured in ch, and nothing is measured in pixels chosen by looking at English. Where a long word genuinely has nowhere left to go, overflow-wrap: break-word lets it break rather than overflow, and hyphens: auto does it properly at syllable boundaries, but only if the element carries the right lang attribute, because the browser will not consult its German hyphenation dictionary for text it has been told is English. Without lang="de" the property silently does nothing.
Second, every layout is checked against the longest translation we have rather than the English. A screenshot of the English version proves nothing whatsoever about the page a Dutch visitor receives.
Third, numbers, dates and currency are formatted by the browser rather than by hand. Intl.NumberFormat is most of it: one call writes $1,234.56 for en-US, € 1.234,56 for nl-NL and 1.234,56 € for de-DE. The decimal comma is the obvious half. The currency symbol moving from the front of the number to the back is the half nobody hand-rolls correctly, and dates are worse still; 26/08/2026 in the UK, 26-8-2026 in the Netherlands, 26.8.2026 in Germany, with the separator and the leading zeros both changing at once.
The fourth habit is closer to an admission. Some components only work at English word lengths, and the honest fix is a different component rather than a shorter word. A row of four buttons reading Length, Weight, Volume, Area fits comfortably across a phone; the same row reading Lengte, Gewicht, Volume, Oppervlakte does not, and the answer there is a select rather than an abbreviation. Choosing the layout that works in the longer language and using it in both is cheaper than maintaining two, and it has the useful side effect that the English page is never the one that got all the attention.
The rules that make it stick
Habits decay, so two of these are enforced by the build rather than by discipline. No user-facing string is allowed to exist inside a component: microcopy lives in a JSON file per locale, and the seed generator fails the build if a key is present in one locale and missing from the other. A half-translated interface is not something that can ship here by accident; it is something that stops the build.
The URLs are translated too, which is a larger commitment than it first sounds. /en/kg-to-lbs is /nl/kg-naar-lbs, linked by a shared key rather than by a shared slug, so the Dutch page is a real page in Dutch and not an English page wearing translated labels. The cost is that every new tool needs its Dutch slug decided at the same time as its English one, and a bad slug is expensive to change once it has been indexed.
The practical test is blunt: paste the German labels into the mortgage calculator at 375 pixels and see what breaks. When the answer is nothing, the layout is done, and when it is not, the fix is almost always in the layout rather than in the translation. Shortening a label until it fits is how interfaces end up reading like a form filled in by a robot, and this site’s voice is worth more than the pixel it would save.