В веб-интерфейсах, рассчитанных на языки с направлением письма справа налево, поведение компонентов формы должно учитывать не только визуальное выравнивание текста, но и логику позиционирования элементов управления. К таким языкам относятся арабский, иврит, персидский и ряд других. При использовании Choices.js поведение селекторов требует дополнительной настройки, поскольку библиотека изначально ориентирована на LTR-макет.
Современные браузеры определяют направление текста через атрибут
dir, применяемый к DOM-элементу:
<html dir="rtl">
или локально:
<div dir="rtl">
<select></select>
</div>
Этот атрибут влияет на:
Однако большинство JavaScript-компонентов, включая Choices.js, не
полагаются полностью на dir, а используют собственные
классы и inline-стили.
При инициализации стандартного селектора:
const element = document.querySelector('select');
const choices = new Choices(element, {
searchEnabled: true,
removeItemButton: true
});
в RTL-контексте проявляются типичные несоответствия:
Эти эффекты особенно заметны в мультиселекте.
Наиболее предсказуемая модель — установка направления на контейнере:
<div class="form-wrapper" dir="rtl">
<select id="countries" multiple></select>
</div>
Choices.js наследует базовое направление, но визуальные компоненты требуют дополнительной CSS-коррекции.
Основная адаптация выполняется через переопределение классов библиотеки.
.choices {
direction: rtl;
text-align: right;
}
.choices__input {
text-align: right;
}
.choices__list--multiple .choices__item {
float: right;
}
Одной из ключевых проблем является направление раскрытия dropdown. По умолчанию Choices.js вычисляет позицию относительно левого края.
Для RTL-режима требуется переопределение:
.choices__list--dropdown {
right: 0;
left: auto;
text-align: right;
}
При необходимости фиксированного позиционирования:
.choices[data-type*="select-one"] .choices__list--dropdown {
right: 0;
left: auto;
}
В RTL-интерфейсе стандартная логика кнопок удаления и стрелок становится визуально некорректной.
.choices__button {
margin-left: 0;
margin-right: 8px;
}
Для крестика удаления в мультиселекте:
.choices__item .choices__button {
float: left;
}
В RTL-среде перенос строк и обтекание элементов может нарушать читаемость выбранных тегов.
Рекомендуемая настройка:
.choices__inner {
white-space: normal;
}
и дополнительное управление переполнением:
.choices__list--multiple {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
}
Поисковый input внутри Choices.js не всегда корректно наследует направление текста.
.choices__input--cloned {
direction: rtl;
text-align: right;
}
При активном поиске важно сохранить поведение курсора справа налево, иначе ввод становится нелогичным для пользователя.
В некоторых интерфейсах направление может меняться в зависимости от локали.
function setDirection(instance, dir) {
const container = instance.containerOuter.element;
container.setAttribute('dir', dir);
}
Пример переключения:
setDirection(choices, 'rtl');
setDirection(choices, 'ltr');
При динамическом изменении направления требуется повторная корректировка dropdown-позиционирования, так как Choices.js не пересчитывает layout автоматически.
В сложных контейнерах с overflow: hidden dropdown может
смещаться в неправильную сторону.
Решение:
.choices__list--dropdown {
position: absolute;
max-width: 100%;
}
и контроль контекста позиционирования:
.form-wrapper {
position: relative;
}
Мультиселект в RTL требует зеркалирования логики потока элементов:
Рекомендуемая модель:
.choices__list--multiple {
display: flex;
flex-direction: row-reverse;
flex-wrap: wrap;
justify-content: flex-start;
}
Наиболее устойчивое поведение достигается при совместном применении HTML-атрибута, CSS и ограниченной логики JS:
<div class="choices-rtl" dir="rtl">
<select multiple></select>
</div>
.choices-rtl .choices {
direction: rtl;
}
.choices-rtl .choices__inner,
.choices-rtl .choices__input {
text-align: right;
}
.choices-rtl .choices__list--dropdown {
right: 0;
left: auto;
}
.choices-rtl .choices__list--multiple {
display: flex;
flex-direction: row-reverse;
}
Сам по себе RTL не увеличивает нагрузку, однако при частых переключениях направления возникают повторные перерасчеты layout:
При большом количестве экземпляров Choices.js это может приводить к заметной задержке при массовых обновлениях DOM.
Фокусное состояние также требует зеркальной логики:
.choices.is-focused {
box-shadow: 0 0 0 2px rgba(0,0,0,0.15);
}
При необходимости усиления визуального контроля:
.choices__inner:focus-within {
border-color: #666;
}
При использовании кастомных тем важно учитывать, что любые абсолютные
значения left и right должны быть
условными.
Типичная ошибка:
.choices__list--dropdown {
left: 0; /* ломает RTL */
}
Корректный подход:
.choices__list--dropdown {
inset-inline-start: auto;
inset-inline-end: 0;
}