Направление текста RTL/LTR

Понятие направления письма в многоязычных интерфейсах

Направление текста является одним из базовых аспектов локализации пользовательских интерфейсов. В международных системах используются два основных типа направления письма:

  • LTR (Left-to-Right) — текст пишется слева направо (английский, русский, большинство европейских языков)
  • RTL (Right-to-Left) — текст пишется справа налево (арабский, иврит, персидский)

Различие затрагивает не только отображение текста, но и структуру интерфейса: расположение элементов навигации, иконок, индикаторов прогресса, таблиц и даже поведения прокрутки.

В контексте JavaScript-библиотеки Globalize направление текста не является функцией форматирования чисел или дат напрямую. Однако оно тесно связано с данными CLDR (Unicode Common Locale Data Repository), на которых основана работа Globalize.


CLDR как источник информации о направлении письма

Globalize использует CLDR как базовый источник локализационных данных. В CLDR содержится отдельный раздел, описывающий ориентацию письма и макета интерфейса:

  • orientation

    • characters (направление символов)
    • lines (направление строк)

Пример структуры CLDR JSON:

{
  "supplemental": {
    "layout": {
      "orientation": {
        "characterOrder": {
          "ar": "right-to-left",
          "he": "right-to-left",
          "en": "left-to-right",
          "ru": "left-to-right"
        }
      }
    }
  }
}

Поле characterOrder определяет базовое направление текста для локали. Эти данные не всегда загружаются автоматически в Globalize, поэтому доступ к ним осуществляется через подключённые JSON-файлы CLDR.


Загрузка данных CLDR в Globalize

Перед использованием информации о направлении текста необходимо загрузить соответствующие CLDR-данные:

import Globalize from "globalize";
import likelySubtags from "cldr-data/supplemental/likelySubtags.json";
import orientation from "cldr-data/supplemental/layout.json";

Globalize.load(likelySubtags);
Globalize.load(orientation);

Дополнительно обычно подключаются языковые данные:

import numbers from "cldr-data/main/ar/numbers.json";
import currencies from "cldr-data/main/ar/currencies.json";
import caGregorian from "cldr-data/main/ar/ca-gregorian.json";

Globalize.load(numbers);
Globalize.load(currencies);
Globalize.load(caGregorian);

После загрузки данных можно работать с локалью:

const globalize = new Globalize("ar");

Определение направления текста через CLDR

Globalize предоставляет доступ к объекту CLDR, через который можно извлекать данные из загруженного репозитория.

const cldr = Globalize.cldr;

const direction =
  cldr.supplemental("layout/orientation/characterOrder");

console.log(direction.ar); // "right-to-left"
console.log(direction.en); // "left-to-right"

Логика определения направления строится на сопоставлении локали и значения characterOrder.


Привязка направления к локали

На практике требуется функция, которая сопоставляет текущую локаль с направлением текста:

function getDirection(locale) {
  const cldr = Globalize.cldr;
  const orientation = cldr.supplemental("layout/orientation/characterOrder");

  const baseLocale = locale.split("-")[0];
  return orientation[baseLocale] || "left-to-right";
}

Использование:

getDirection("ar-EG"); // "right-to-left"
getDirection("en-US"); // "left-to-right"

Интеграция с DOM и атрибутом dir

В веб-интерфейсах направление текста контролируется атрибутом dir:

  • dir="ltr"
  • dir="rtl"

Привязка CLDR-данных к DOM:

const locale = "ar";
const direction = getDirection(locale);

document.documentElement.setAttribute("dir", direction);
document.documentElement.setAttribute("lang", locale);

Это влияет на:

  • порядок отображения текста
  • выравнивание блоков
  • направление inline-элементов
  • поведение flex и grid при использовании direction: rtl

CSS и влияние direction на layout

CSS поддерживает логические свойства, которые автоматически адаптируются к направлению текста.

Пример базового поведения

.container {
  text-align: start;
  margin-inline-start: 10px;
  padding-inline-end: 20px;
}

В LTR:

  • start = left
  • end = right

В RTL:

  • start = right
  • end = left

Globalize не управляет CSS напрямую, но через определение локали может быть связан с системой, которая динамически применяет классы или атрибуты.


Переключение интерфейса на основе локали Globalize

Globalize используется как источник локали, а направление текста становится производным параметром:

const globalize = new Globalize("he");
const locale = globalize.cldr.locale.attributes.language.id;

const direction = getDirection(locale);

document.documentElement.dir = direction;

В многоязычных приложениях часто применяется централизованный контроллер локализации:

function applyLocale(locale) {
  const g = new Globalize(locale);

  const direction = getDirection(locale);

  document.documentElement.setAttribute("lang", locale);
  document.documentElement.setAttribute("dir", direction);

  return g;
}

RTL и особенности отображения чисел и дат

Важно учитывать, что направление текста не влияет на форматирование чисел и дат внутри Globalize:

  • числа остаются в своей визуальной форме
  • разделители тысяч и десятичные знаки зависят от локали
  • порядок компонентов даты определяется культурой, а не направлением письма

Пример:

const g = new Globalize("ar");

g.formatNumber(1234567.89);
// "١٬٢٣٤٬٥٦٧٫٨٩"

Несмотря на RTL-локаль, числовые значения сохраняют корректное представление согласно CLDR.


Механизмы смешанного текста (BiDi)

В интерфейсах часто встречается смешанный текст:

  • арабский текст + латинские слова
  • числа внутри RTL предложений
  • URL внутри RTL блоков

Unicode Bidirectional Algorithm автоматически определяет порядок отображения, но HTML-атрибут dir задаёт базовое направление.

<p dir="rtl">
  هذا نص يحتوي English words و 123 numbers
</p>

Globalize в данном случае отвечает только за локализацию данных, а не за алгоритм BiDi.


Использование локали для управления иконографикой и UI-элементами

Направление текста влияет не только на строки, но и на визуальную структуру интерфейса:

  • стрелки навигации
  • индикаторы слайдеров
  • прогресс-бары
  • иконки «назад/вперёд»

Пример логического переключения:

const isRTL = getDirection(locale) === "right-to-left";

const icon = isRTL ? "arrow-left" : "arrow-right";

Связь Globalize и системной архитектуры i18n

Globalize выполняет роль поставщика локализованных данных:

  • числа
  • валюты
  • даты и времена
  • сообщения

Direction текста извлекается из CLDR как дополнительный параметр локали и используется в UI-слое.

Архитектура обычно разделяется на уровни:

  1. Data layer (Globalize + CLDR)
  2. Localization service (выбор locale)
  3. Presentation layer (DOM/CSS/React/Vue)

Динамическое переключение направления в SPA

В одностраничных приложениях направление может меняться без перезагрузки:

function switchLocale(locale) {
  const g = new Globalize(locale);

  const direction = getDirection(locale);

  document.documentElement.dir = direction;
  document.documentElement.lang = locale;

  updateApp(g);
}

Изменения затрагивают весь layout, поэтому часто требуется перерисовка компонентов интерфейса.


Ошибки при работе с RTL в локализации

Распространённые проблемы:

  • игнорирование атрибута dir
  • использование фиксированных margin-left/right
  • отсутствие логических CSS свойств
  • неправильное зеркалирование иконок
  • смешивание LTR-логики в RTL интерфейсе

Globalize не предотвращает эти ошибки, но предоставляет корректную локализационную основу через CLDR.


Поведение layout при наследовании направления

Направление текста наследуется по DOM-иерархии:

<div dir="rtl">
  <section>
    <p>текст</p>
  </section>
</div>

Все вложенные элементы автоматически получают RTL-направление, если не переопределено локально.


Практическая связка Globalize и UI-слоя

Типичная схема использования:

import Globalize from "globalize";

function initLocale(locale) {
  const g = new Globalize(locale);

  const dir = getDirection(locale);

  document.documentElement.setAttribute("lang", locale);
  document.documentElement.setAttribute("dir", dir);

  return {
    formatNumber: g.formatNumber.bind(g),
    formatDate: g.formatDate.bind(g),
    formatCurrency: g.formatCurrency.bind(g)
  };
}

UI-слой использует возвращённые функции, а направление текста применяется глобально на уровне DOM.


Поведение flex и grid в RTL/LTR

CSS Flexbox и Grid адаптируются к direction:

  • flex-start и flex-end меняются местами
  • grid-column-start логически инвертируется
  • порядок элементов может визуально зеркалироваться
.container {
  display: flex;
  justify-content: space-between;
}

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


Итоговая роль direction в экосистеме Globalize

Direction текста в Globalize является не встроенной функцией форматирования, а производным значением из CLDR-данных. Он используется как связующий параметр между локализацией данных и визуальным представлением интерфейса, обеспечивая корректную адаптацию LTR и RTL языков в единой архитектуре приложения.