Тег bdi в HTML: что это и как изолировать направление текста

Тег bdi (от английского bidirectional isolate, «двунаправленная изоляция») отделяет фрагмент текста от окружения при выборе направления написания. Он нужен, когда в строку попадает текст, направление которого автор не знает заранее: имя пользователя, заголовок комментария, название из базы данных. Тег парный, собственных атрибутов у него нет, а атрибут dir по умолчанию действует как auto: браузер сам определяет направление по содержимому.

Без bdi беда случается не с самим именем, а с тем, что рядом: если имя пользователя написано справа налево, соседние число, двоеточие или скобка могут оказаться не с той стороны. Автору такая строка при проверке обычно не встречается, потому что тестовые имена почти всегда латинские. Чем bdi отличается от span с dir="auto", а также от тега bdo, показано ниже.

HTML
<p>Игрок: <bdi>שלום</bdi> - 5</p>

Тег bdi в HTML: что это и для чего нужен

Слова идут слева направо (русский, английский) или справа налево (арабский, иврит). Когда в строку с одним направлением попадает текст с другим, браузер по алгоритму двунаправленного текста решает, как выстроить слова, числа и знаки препинания рядом. Иногда решение ломает порядок: число или знак рядом с чужим текстом переезжает на другую сторону.

Тег bdi изолирует свой текст: то, что внутри, не влияет на порядок снаружи, а окружение не влияет на порядок внутри. Направление внутри определяется по первому знаку с явным направлением. В Chrome bdi - строчный элемент (display: inline) со свойством unicode-bidi: isolate, а вычисленное направление для арабского имени равно rtl, хотя атрибута dir в разметке нет.

Спецификация указывает главный случай применения: пользовательский текст с неизвестным направлением. По данным справки MDN, тег доступен во всех современных браузерах с января 2020 года. Сам текст тег не меняет: выделение и textContent остаются в обычном порядке, меняется только показ.

Что ломается без тега bdi: имя, число и знаки рядом

Возьмём строку из таблицы результатов: «Игрок: имя - 5». Если имя записано на иврите или по-арабски, а вокруг русский текст, знак «-» и число «5» оказываются слева от имени, а не справа. В замере порядок кусков слева направо был такой: «Игрок:», «- 5», имя. С bdi порядок верный: «Игрок:», имя, «- 5».

HTML
<p>Игрок: <span>שלום</span> - 5</p>

<p>Игрок: <bdi>שלום</bdi> - 5</p>

Так же ломаются строки «имя - 5 очков», «1. имя: 5», «Игрок имя, 5» и «имя (5)». Строки «Игрок имя!» и «Игрок имя: Anna» в замере не ломались. Поэтому риск не оценить по одной удачной строке: имя записывает пользователь, а проверять нужно любой язык.

Проверьте сами в кадре: выберите имя и способ записи, кадр измерит порядок кусков. Можно ввести своё имя.

Пример: где оказывается счёт рядом с именем

Результат

Выберите имя и способ записи. Кадр измеряет положение кусков строки и показывает, где оказался счёт.

Тег bdi, span dir=auto и атрибут dir: что выбрать

Изоляцию можно получить тремя способами. Первый - тег bdi. Второй - <span dir="auto">: в замере он получил такие же unicode-bidi: isolate и направление по содержимому. Третий - CSS-свойство unicode-bidi: isolate у обычного span: изоляция есть, но направление остаётся ltr, потому что автоопределения нет. Для арабского имени порядок кусков в кадре выше у всех трёх способов верный.

Между bdi и span dir=auto разница в смысле: bdi прямо говорит, что здесь изолированный текст, и короче. По справке MDN, стили браузер или сторонняя среда могут проигнорировать, а тег остаётся, поэтому для этого случая лучше тег.

Атрибут dir у bdi можно задать явно: ltr и rtl фиксируют направление, а auto возвращает автоопределение. Явное значение нужно, когда направление известно заранее, например язык поля.

HTML
<bdi>שלום</bdi>
<bdi dir="ltr">שלום</bdi>
<bdi dir="rtl">Anna</bdi>

Явное значение опасно, если язык неизвестен. У имени на иврите со знаком в конце в замере: без dir и с dir=auto знак «!» стоит слева от букв, как принято в иврите, а с dir=ltr оказывается справа. С dir=rtl латинское имя «Anna!» получает «!» слева, а не справа.

Пример: атрибут dir у bdi

Результат

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

Тег bdi и bdo: изоляция против принудительного направления

Тег bdi направление не меняет: он выбирает его по содержимому и изолирует. Тег bdo действует наоборот: атрибутом dir он принудительно задаёт направление, и буквы латинского слова в dir=rtl идут задом наперёд. Изоляция у bdo получается попутно (в замере unicode-bidi: isolate-override).

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

Пример: bdi и bdo на одном слове

Результат

Выберите запись. Кадр показывает порядок букв на экране и текст, который попадёт в копию.

Частые ошибки с тегом bdi

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

ОшибкаЧто происходитКак исправить
Имя пользователя без изоляции: Игрок: <span>שלום</span> - 5Счёт и знаки рядом с арабским именем или именем на иврите оказываются слева от негоОбернуть имя в bdi
bdo вместо bdi для имёнbdo принудительно меняет направление: латинские буквы идут задом наперёдИспользовать bdi, он выбирает направление по содержимому
Проверка только на русских и английских именахПорядок ломается лишь на тексте с другим направлением, и ошибку не видноПроверить строку с арабским именем и именем на иврите
Явный dir="ltr" для имени, язык которого неизвестенЗнак «!» в конце имени на иврите оказывается справа от букв, а не слеваНе задавать dir: по умолчанию действует auto
Ожидание, что bdi изменит копируемый текстМеняется только показ, копия остаётся в обычном порядкеПорядок в самом тексте не менять
Категория
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×