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

или нажмите, чтобы выбрать

Целевые языки

Регистрация не требуетсяМгновенный расчёт

Частые вопросы об увеличении текста