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

Направление текста является фундаментальным параметром локализации интерфейсов. Большинство языков мира используют порядок письма слева направо (LTR — left-to-right), однако значительная группа языков опирается на обратное направление (RTL — right-to-left), включая арабский и иврит. В контексте JavaScript API интернационализации управление направлением текста интегрировано через модель локалей и стандарты Unicode CLDR.

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

В основе интернационализации в JavaScript лежит объект локали, представленный через Intl.Locale. Он инкапсулирует метаданные языка, региона и письма, включая сведения о типографических и поведенческих особенностях.

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

const locale = new Intl.Locale("ar-EG");

В данном случае локаль указывает на арабский язык в Египте, где стандартным направлением письма является RTL.

Свойство textInfo и определение направления

Современная спецификация ECMAScript Internationalization API добавляет объект textInfo в Intl.Locale. Он содержит информацию о направлении текста, доступную через свойство direction.

const locale = new Intl.Locale("ar-EG");

console.log(locale.textInfo.direction);
// "rtl"

Возможные значения:

  • ltr — текст пишется слева направо
  • rtl — текст пишется справа налево

Если информация недоступна или не поддерживается средой выполнения, значение может отсутствовать (undefined), что требует резервной логики.

Автоматическое определение направления через локаль

Определение направления строится на базе Unicode CLDR (Common Locale Data Repository), где каждому языку и письменности сопоставлены характеристики направления письма.

Примеры локалей с RTL-направлением:

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

Примеры LTR:

  • en — английский
  • ru — русский
  • fr — французский
  • de — немецкий
const locales = ["en-US", "ar", "he", "fa", "ru"];

for (const tag of locales) {
  const loc = new Intl.Locale(tag);
  console.log(tag, loc.textInfo?.direction);
}

Результат зависит от поддержки окружения, но логика остаётся неизменной: направление извлекается из данных локали.

Связь направления текста и Unicode bidi-алгоритма

Unicode Bidirectional Algorithm (Bidi) определяет порядок отображения символов при смешанном тексте. JavaScript не управляет этим алгоритмом напрямую, но данные из Intl.Locale позволяют предсказать поведение текста.

При смешивании RTL и LTR сегментов используется контекстная перестановка символов:

  • числа обычно сохраняют LTR-порядок
  • латиница в RTL-тексте инкапсулируется направляющими маркерами
  • знаки пунктуации следуют базовому направлению абзаца

Практическое использование direction в интерфейсах

Информация о направлении текста используется для установки атрибутов HTML и CSS-логики:

const locale = new Intl.Locale("ar");
const direction = locale.textInfo?.direction;

document.documentElement.dir = direction || "ltr";

Атрибут dir влияет на поведение блочной модели, выравнивание текста и направление потока элементов.

В CSS это связано с логическими свойствами:

  • margin-inline-start
  • padding-inline-end
  • text-align: start

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

Динамическое переключение интерфейса

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

function applyLocale(tag) {
  const locale = new Intl.Locale(tag);
  const dir = locale.textInfo?.direction ?? "ltr";

  document.documentElement.lang = locale.language;
  document.documentElement.dir = dir;
}

applyLocale("he");

Такой подход обеспечивает согласованность текста, иконографии и layout-модели.

Ограничения и особенности поддержки

Поддержка textInfo.direction зависит от версии движка JavaScript. В некоторых окружениях информация может отсутствовать, несмотря на корректную локаль.

В таких случаях применяется fallback-логика на основе списка RTL-языков:

const rtlLanguages = new Set(["ar", "he", "fa", "ur", "ps", "dv"]);

function getDirection(localeStr) {
  const locale = new Intl.Locale(localeStr);
  const lang = locale.language;
  return rtlLanguages.has(lang) ? "rtl" : "ltr";
}

Такой подход не учитывает все нюансы письменностей, но обеспечивает стабильное поведение.

Взаимодействие с форматированием Intl API

Другие компоненты Intl также косвенно зависят от направления текста:

  • Intl.DateTimeFormat — порядок компонентов даты может визуально меняться в RTL
  • Intl.NumberFormat — группировка чисел сохраняет LTR-структуру
  • Intl.RelativeTimeFormat — строки локализации могут иметь разный порядок слов
const fmt = new Intl.DateTimeFormat("ar", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

console.log(fmt.format(new Date()));

Результат форматирования может отличаться не только словами, но и визуальной структурой из-за RTL-контекста.

Контекстные сценарии в сложных интерфейсах

В приложениях с гибридной локализацией (например, таблицы, CRM-системы, редакторы) направление текста влияет на:

  • порядок колонок
  • позиционирование кнопок навигации
  • направление свайпов и жестов
  • ориентацию иконок «назад/вперёд»

Использование Intl.Locale позволяет централизовать управление этими аспектами, избегая разрозненных проверок по коду.

function isRTL(localeStr) {
  const locale = new Intl.Locale(localeStr);
  return locale.textInfo?.direction === "rtl";
}

const rtl = isRTL("fa-IR");

Роль письменности (script) в определении направления

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

  • Arab — арабское письмо (RTL)
  • Hebr — еврейское письмо (RTL)
  • Latn — латиница (LTR)
const locale = new Intl.Locale("ar");
console.log(locale.script);

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

Согласование UI и семантики текста

Корректная работа с RTL/LTR требует согласованности между:

  • семантикой HTML (dir, lang)
  • форматированием Intl API
  • CSS логическими свойствами
  • внутренними алгоритмами bidi

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

Использование в многоуровневой локализации

В крупных системах направление текста становится частью локализационного профиля:

const locale = new Intl.Locale("ur-PK");

const profile = {
  language: locale.language,
  region: locale.region,
  direction: locale.textInfo?.direction
};

Такая модель позволяет унифицировать поведение интерфейса на уровне конфигурации, а не отдельных компонентов.