Поддержка языков с направлением письма справа налево (RTL — Right-to-Left) требует согласованной работы уровня интернационализации, DOM-структуры и CSS-стилей. В экосистеме i18next управление языковыми направлениями не ограничивается выбором перевода строк: необходимо учитывать изменение логики отображения интерфейса, порядок визуальных блоков и поведение встроенных компонентов браузера.
Языки делятся по направлению письма:
Направление текста влияет не только на выравнивание символов, но и на:
Браузер предоставляет базовую поддержку через атрибут
dir, однако интернационализационный слой должен
синхронизировать языковое состояние с этим атрибутом.
В i18next направление текста не является автоматическим результатом выбора языка. Библиотека предоставляет язык, но не навязывает UI-логику. Поэтому направление определяется на основе текущего языка.
Типичная логика определения RTL:
ar)he)fa)ur)Эти языки требуют установки dir="rtl".
Пример функции определения:
const rtlLanguages = ['ar', 'he', 'fa', 'ur'];
function getDirection(lng) {
return rtlLanguages.includes(lng) ? 'rtl' : 'ltr';
}
Основной механизм синхронизации заключается в обновлении атрибутов документа при смене языка:
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-слоя.
Установка dir="rtl" активирует базовое зеркалирование
текста, но не гарантирует корректное отображение интерфейса.
Критические CSS-моменты:
body {
text-align: start;
}
Использование start/end вместо left/right
обеспечивает автоматическую адаптацию.
.container {
display: flex;
flex-direction: row;
}
При RTL порядок элементов меняется визуально, но логика DOM остаётся прежней. Для контроля используется:
.container {
flex-direction: row-reverse;
}
либо более современный подход:
.container {
direction: ltr; /* или rtl в зависимости от контекста */
}
Современная поддержка RTL базируется на логических свойствах:
margin-inline-startmargin-inline-endpadding-inlineborder-inlineПример:
.card {
padding-inline: 16px;
margin-inline-start: 12px;
}
Это устраняет необходимость дублирования правил для разных направлений.
i18next предоставляет систему ресурсов и переключения языков, но не управляет layout-слоем. Поэтому архитектура обычно разделяется на уровни:
Языковой слой (i18next)
UI-слой
dirКомпонентный слой
Часто направление определяется централизованно через конфигурацию:
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 не ограничивается сменой направления текста. Основная сложность — визуальная симметрия интерфейса.
Типовые проблемы:
Решение требует условного рендеринга:
const isRTL = getDirection(i18next.language) === 'rtl';
const arrow = isRTL ? '←' : '→';
SVG-иконки могут зеркалироваться через CSS:
[dir="rtl"] .icon-flip {
transform: scaleX(-1);
}
Альтернативный подход — логическое управление:
const directionMultiplier = isRTL ? -1 : 1;
При использовании браузерного окружения важна синхронизация:
Плагин определения языка (language detector) часто возвращает язык без учёта направления, поэтому требуется дополнительная обработка.
i18next.init({
detection: {
order: ['navigator', 'htmlTag', 'path']
}
});
После инициализации:
updateDocumentLanguage(i18next.language);
При смене языка интерфейс должен мгновенно перестраиваться.
Критические элементы:
Анимации могут требовать инверсии:
@keyframes slide-in {
from {
transform: translateX(-20px);
}
to {
transform: translateX(0);
}
}
[dir="rtl"] @keyframes slide-in {
from {
transform: translateX(20px);
}
}
Хотя i18next не требует хранения metadata в ресурсах, иногда используется расширенная структура:
const resources = {
ar: {
translation: {
dir: 'rtl',
greeting: 'مرحبا'
}
}
};
Однако более чистый подход — разделение переводов и метаданных.
Корректная реализация требует единых правил:
Формы в RTL требуют внимания к:
Пример:
input {
text-align: start;
}
Для сложных форм используется разделение:
dir)В компонентах важно избегать «жёсткого» позиционирования:
left: 0 заменяется на
inset-inline-startright: 0 заменяется на
inset-inline-endЭто обеспечивает корректную работу RTL без дублирования стилей.
RTL влияет на:
.scroll-container {
direction: rtl;
overflow-x: auto;
}
При этом логика программного scroll может требовать инверсии координат.
Архитектурно взаимодействие можно представить как цепочку:
document.documentElement.dirТакая модель обеспечивает согласованность интерфейса при смене языков с разным направлением письма и исключает необходимость ручного дублирования интерфейсных слоёв для RTL и LTR вариантов.