RTL языки и направление текста

Поддержка языков с направлением письма справа налево (RTL — Right-to-Left) требует согласованной работы уровня интернационализации, DOM-структуры и CSS-стилей. В экосистеме i18next управление языковыми направлениями не ограничивается выбором перевода строк: необходимо учитывать изменение логики отображения интерфейса, порядок визуальных блоков и поведение встроенных компонентов браузера.

RTL и LTR как фундаментальное свойство языка

Языки делятся по направлению письма:

  • LTR (Left-to-Right): английский, немецкий, русский, французский
  • RTL (Right-to-Left): арабский, иврит, персидский, урду

Направление текста влияет не только на выравнивание символов, но и на:

  • порядок расположения UI-элементов
  • направление навигации
  • интерпретацию иконок (стрелки, карусели, слайдеры)
  • логическую структуру flex/grid контейнеров

Браузер предоставляет базовую поддержку через атрибут dir, однако интернационализационный слой должен синхронизировать языковое состояние с этим атрибутом.

Определение направления языка в i18next

В i18next направление текста не является автоматическим результатом выбора языка. Библиотека предоставляет язык, но не навязывает UI-логику. Поэтому направление определяется на основе текущего языка.

Типичная логика определения RTL:

  • арабский (ar)
  • иврит (he)
  • персидский (fa)
  • урду (ur)

Эти языки требуют установки dir="rtl".

Пример функции определения:

const rtlLanguages = ['ar', 'he', 'fa', 'ur'];

function getDirection(lng) {
  return rtlLanguages.includes(lng) ? 'rtl' : 'ltr';
}

Связь i18next и DOM-атрибутов

Основной механизм синхронизации заключается в обновлении атрибутов документа при смене языка:

  • lang — язык документа
  • dir — направление текста

При изменении языка через i18next необходимо обновлять DOM:

import i18next from 'i18next';

function updateDocumentLanguage(lng) {
  document.documentElement.lang = lng;
  document.documentElement.dir = getDirection(lng);
}

Событие изменения языка:

i18next.on('languageChanged', (lng) => {
  updateDocumentLanguage(lng);
});

Таким образом, состояние интернационализации становится источником правды для UI-слоя.

CSS-аспекты поддержки RTL

Установка dir="rtl" активирует базовое зеркалирование текста, но не гарантирует корректное отображение интерфейса.

Критические CSS-моменты:

Выравнивание текста

body {
  text-align: start;
}

Использование start/end вместо left/right обеспечивает автоматическую адаптацию.

Flexbox и направление

.container {
  display: flex;
  flex-direction: row;
}

При RTL порядок элементов меняется визуально, но логика DOM остаётся прежней. Для контроля используется:

.container {
  flex-direction: row-reverse;
}

либо более современный подход:

.container {
  direction: ltr; /* или rtl в зависимости от контекста */
}

Логические свойства CSS

Современная поддержка RTL базируется на логических свойствах:

  • margin-inline-start
  • margin-inline-end
  • padding-inline
  • border-inline

Пример:

.card {
  padding-inline: 16px;
  margin-inline-start: 12px;
}

Это устраняет необходимость дублирования правил для разных направлений.

Интеграция RTL в архитектуру i18next

i18next предоставляет систему ресурсов и переключения языков, но не управляет layout-слоем. Поэтому архитектура обычно разделяется на уровни:

  1. Языковой слой (i18next)

    • хранение переводов
    • управление текущим языком
    • обработка fallback-языков
  2. UI-слой

    • установка dir
    • применение CSS-режима
    • управление компонентами
  3. Компонентный слой

    • адаптация иконок
    • изменение поведения навигации
    • зеркалирование элементов

Определение RTL на уровне конфигурации

Часто направление определяется централизованно через конфигурацию:

const i18nConfig = {
  lng: 'en',
  fallbackLng: 'en',
  resources: {},
  postProcess: false
};

Добавляется слой метаданных языков:

const languageMeta = {
  en: { dir: 'ltr' },
  ar: { dir: 'rtl' },
  he: { dir: 'rtl' }
};

При переключении языка:

function setLanguage(lng) {
  i18next.changeLanguage(lng);
  document.documentElement.dir = languageMeta[lng]?.dir || 'ltr';
}

Проблема зеркалирования интерфейса

RTL не ограничивается сменой направления текста. Основная сложность — визуальная симметрия интерфейса.

Типовые проблемы:

  • стрелки навигации продолжают указывать вправо
  • иконки «назад/вперёд» теряют смысл
  • карусели прокручиваются в неверную сторону
  • порядок breadcrumb остаётся LTR

Решение требует условного рендеринга:

const isRTL = getDirection(i18next.language) === 'rtl';

const arrow = isRTL ? '←' : '→';

Работа с иконками и SVG

SVG-иконки могут зеркалироваться через CSS:

[dir="rtl"] .icon-flip {
  transform: scaleX(-1);
}

Альтернативный подход — логическое управление:

const directionMultiplier = isRTL ? -1 : 1;

i18next-browser integration и RTL

При использовании браузерного окружения важна синхронизация:

  • начальная установка языка
  • определение языка пользователя
  • применение direction до первого рендера

Плагин определения языка (language detector) часто возвращает язык без учёта направления, поэтому требуется дополнительная обработка.

i18next.init({
  detection: {
    order: ['navigator', 'htmlTag', 'path']
  }
});

После инициализации:

updateDocumentLanguage(i18next.language);

Динамическое переключение RTL

При смене языка интерфейс должен мгновенно перестраиваться.

Критические элементы:

  • layout контейнеры
  • модальные окна
  • всплывающие подсказки
  • анимации переходов

Анимации могут требовать инверсии:

@keyframes slide-in {
  from {
    transform: translateX(-20px);
  }
  to {
    transform: translateX(0);
  }
}

[dir="rtl"] @keyframes slide-in {
  from {
    transform: translateX(20px);
  }
}

Хранение направлений в ресурсах i18next

Хотя i18next не требует хранения metadata в ресурсах, иногда используется расширенная структура:

const resources = {
  ar: {
    translation: {
      dir: 'rtl',
      greeting: 'مرحبا'
    }
  }
};

Однако более чистый подход — разделение переводов и метаданных.

Формирование устойчивой RTL-архитектуры

Корректная реализация требует единых правил:

  • направление определяется только языком
  • DOM синхронизируется через единый handler
  • CSS использует логические свойства
  • иконки не зависят от физического направления
  • компоненты не хранят локальное знание RTL

Особенности работы с формами

Формы в RTL требуют внимания к:

  • порядку label → input
  • выравниванию placeholder
  • направлению ввода чисел и текста

Пример:

input {
  text-align: start;
}

Для сложных форм используется разделение:

  • визуальное направление (dir)
  • логическое поведение (валидация, маски)

Взаимодействие с компонентными фреймворками

В компонентах важно избегать «жёсткого» позиционирования:

  • left: 0 заменяется на inset-inline-start
  • right: 0 заменяется на inset-inline-end

Это обеспечивает корректную работу RTL без дублирования стилей.

Поведение скролла и контейнеров

RTL влияет на:

  • горизонтальный scroll
  • позицию scrollbar
  • начальную точку прокрутки
.scroll-container {
  direction: rtl;
  overflow-x: auto;
}

При этом логика программного scroll может требовать инверсии координат.

Итоговая модель взаимодействия i18next и RTL

Архитектурно взаимодействие можно представить как цепочку:

  • язык выбирается в i18next
  • язык маппится в направление текста
  • направление устанавливается в document.documentElement.dir
  • CSS адаптируется через логические свойства
  • компоненты реагируют на direction через условную логику

Такая модель обеспечивает согласованность интерфейса при смене языков с разным направлением письма и исключает необходимость ручного дублирования интерфейсных слоёв для RTL и LTR вариантов.