Skip to main content

Розширення тексту в i18n: як запобігти порушенню макета через довжину перекладу

Ваш англомовний інтерфейс має бездоганний вигляд. Аж ось надходить німецький переклад — на 30% довший. Фінський — на 40%. Текст виходить за межі кнопок, таблиці деформуються, а ретельно спроєктований макет руйнується. Тестування розширення тексту допомагає цьому запобігти.

1

Чому розширення тексту порушує макети

Розробники проєктують інтерфейси з англійським текстом, а англійська — одна з найкомпактніших мов. Коли надходять переклади, довший текст виходить за межі контейнерів, порушує сіткові макети, обрізає підписи кнопок і виштовхує вміст за межі екрана. Такі помилки виникають лише в окремих локалях, тому залишаються непомітними під час розробки й тестування тільки англійською мовою.

The expansion problem
// 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.
Розширення тексту — не рідкісний виняток. З ним зіткнеться кожен інтерфейс із підтримкою кількох мов. Німецький текст на 30% довший за англійський, фінський — на 40%, а в деяких мовах короткі рядки можуть бути довшими більш ніж на 100%. Тестування розширення до надходження перекладів дає змогу уникнути дорогого перепроєктування.
2

Коефіцієнти розширення тексту за мовами

Середні коефіцієнти розширення порівняно з англійським вихідним текстом. Короткі рядки (до 20 символів) розширюються більше за довгі, оскільки вибір окремих слів сильніше впливає на загальну довжину.

Expansion ratios by language
// 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% expansion
Це середні значення. Окремі рядки можуть розширюватися значно більше — англійський підпис кнопки з 2 слів німецькою може складатися з 4 слів. Для критично важливих елементів інтерфейсу, як-от кнопки, навігація та заголовки таблиць, тестуйте з вищими коефіцієнтами (понад 50%).
3

Тестування за допомогою i18n-pseudo

Стратегія розширення i18n-pseudo додає заповнення до вихідних рядків, щоб імітувати довжину перекладу. Установіть коефіцієнт розширення відповідно до цільових мов і протестуйте макети ще до надходження справжніх перекладів.

Terminal
# 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
Visual regression tests
// 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,
  });
});
Тестуйте з розширенням на 40% для європейських мов і на 50% для найскладніших сценаріїв. Якщо макет витримує розширення на 50%, він працюватиме практично з будь-якою мовою.
4

Найкращі практики проєктування для i18n

Щоб створити макети, здатні вмістити розширений текст, проєктні рішення потрібно ухвалити ще до початку перекладу. Ці практики запобігають найпоширенішим помилкам, пов’язаним із розширенням.

CSS best practices
/* 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 */

Спробуйте i18n Agent зараз

Перетягніть сюди файл для перекладу

JSON, YAML, PO, XML, CSV, Markdown, Properties

або натисніть, щоб вибрати

Цільові мови

Реєстрація не потрібнаМиттєвий розрахунок

Поширені запитання про розширення тексту