
Rozšírenie textu v i18n: predchádzajte narušeniu rozloženia dĺžkou prekladu
Vaše anglické rozhranie dokonale sedí. Potom dorazia nemecké preklady – o 30 % dlhšie. Fínske sú dlhšie o 40 %. Tlačidlá pretečú, tabuľky sa narušia a starostlivo navrhnuté rozloženie sa rozpadne. Testovanie rozšírenia textu tomu predchádza.
Prečo rozšírenie textu narúša rozloženie
Vývojári navrhujú používateľské rozhrania s anglickým textom, ktorý patrí medzi najkompaktnejšie jazyky. Keď dorazia preklady, dlhšie jazyky pretekajú z kontajnerov, narúšajú mriežkové rozloženia, skracujú štítky tlačidiel a vytláčajú obsah mimo obrazovky. Tieto chyby sa prejavujú iba v konkrétnych lokalizáciách, preto zostávajú počas vývoja a testovania len v angličtine neviditeľné.
// English is one of the most compact languages.
// Translations are almost always LONGER.
// English (source):
"Save" // 4 chars
// Translations:
"Speichern" // German: 10 chars (+150%)
"Enregistrer" // French: 12 chars (+200%)
"Guardar" // Spanish: 7 chars (+75%)
"Сохранить" // Russian: 9 chars (+125%)
"Tallenna" // Finnish: 8 chars (+100%)
// Buttons, labels, and table headers designed for
// English text WILL break in other languages.Pomery rozšírenia textu podľa jazyka
Priemerné pomery rozšírenia oproti anglickému zdrojovému textu. Krátke reťazce (menej ako 20 znakov) sa rozširujú viac než dlhé, pretože voľba jednotlivých slov má väčší vplyv na celkovú dĺžku.
// Average text expansion relative to English:
// European languages:
// German: +30-35% (compound words)
// Finnish: +30-40% (agglutinative)
// French: +15-25% (articles, prepositions)
// Spanish: +15-25%
// Italian: +15-25%
// Portuguese: +15-25%
// Russian: +20-30% (case endings)
// Polish: +20-30%
// Greek: +20-30%
// Asian languages (CJK):
// Chinese: -30-50% (shorter in characters, but wider per char)
// Japanese: -20-40% (kanji compress meaning)
// Korean: -10-20%
// Right-to-left:
// Arabic: +20-30%
// Hebrew: +10-20%
// Rule of thumb by source string length:
// 1-10 chars: expect +200% expansion
// 11-20 chars: expect +80% expansion
// 21-70 chars: expect +40% expansion
// 71+ chars: expect +30% expansionTestovanie pomocou i18n-pseudo
Stratégia rozšírenia i18n-pseudo pridáva k zdrojovým reťazcom výplň, ktorá simuluje dĺžku prekladu. Nastavte pomer rozšírenia podľa svojich cieľových jazykov a otestujte rozloženia skôr, než dorazia skutočné preklady.
# Method 1: Pseudo-localization with expansion
npx i18n-pseudo generate \
--source locales/en.json \
--output locales/pseudo-expanded.json \
--expansion 1.4 \
--preset expanded
# Method 2: Longest-translation analysis
npx i18n-validate expansion \
--source locales/en.json \
--targets 'locales/*.json' \
--report expansion-report.json
# Output:
# Key | EN | Longest | Lang | Ratio
# ---------------------|-----|---------|------|-------
# nav.settings | 8 | 14 | de | 175%
# buttons.save | 4 | 12 | fr | 300%
# errors.networkFailed | 14 | 28 | fi | 200%
# Method 3: Visual regression with expanded text
npx playwright test \
--project=expansion-test \
--update-snapshots// playwright.config.ts
export default defineConfig({
projects: [
{
name: 'expansion-test',
use: {
locale: 'pseudo-expanded',
},
},
],
});
// tests/expansion.spec.ts
test('buttons do not overflow with expanded text', async ({ page }) => {
await page.goto('/');
// Check no horizontal overflow
const buttons = await page.locator('button').all();
for (const button of buttons) {
const box = await button.boundingBox();
const parent = await button.locator('..').boundingBox();
expect(box!.x + box!.width).toBeLessThanOrEqual(
parent!.x + parent!.width
);
}
// Visual snapshot comparison
await expect(page).toHaveScreenshot('homepage-expanded.png', {
maxDiffPixels: 100,
});
});Osvedčené dizajnové postupy pre i18n
Tvorba rozložení, ktoré zvládajú rozšírenie textu, si vyžaduje dizajnové rozhodnutia ešte pred začiatkom prekladania. Tieto postupy predchádzajú najbežnejším chybám súvisiacim s rozšírením.
/* 1. Use flexible containers, not fixed widths */
/* WRONG */
.button { width: 120px; }
/* RIGHT */
.button { min-width: 80px; padding: 8px 16px; }
/* 2. Allow text wrapping in labels */
/* WRONG */
.label { white-space: nowrap; overflow: hidden; }
/* RIGHT */
.label { overflow-wrap: break-word; }
/* 3. Use CSS Grid/Flexbox for adaptive layouts */
.nav {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
/* 4. Reserve space for the longest expected translation */
/* Use min-width based on ~1.4x English length */
.table-header {
min-width: max-content;
padding-right: 16px;
}
/* 5. Test with the longest language first */
/* German and Finnish are good stress-test languages */
/* 6. For CJK: account for wider characters */
/* CJK characters are typically 2x the width of Latin chars */
/* Even though text is shorter, it may be wider visually */Vyskúšajte i18n Agent teraz
Potiahnite súbor na preklad sem
JSON, YAML, PO, XML, CSV, Markdown, Properties
alebo kliknite a vyberte súbor
Cieľové jazyky