Хабр, я снова пришёл к вам с практическими советами про доступность вместе с Ильёй. Мы показываем, как HTML и CSS могут улучшить или ухудшить её. Напоминаю, что Илья — мой незрячий знакомый, который помогает мне найти наши косяки в вёрстке.

Сегодня мы рассмотрим следующие аспекты:

  • где полезно использовать элемент search;

  • существующие проблемы при использовании единиц измерения от размеров вьюпорта для установки размера текста;

  • как элемент hr влияет на опыт пользователей скринридера;

  • нужны ли заголовки модальным окнам.

Давайте начнём!

Элемент search добавляет больше информации

Меня удивляет, что фронтендеры очень мало используют элемент search. Коллеги, он поддерживается в большинстве браузеров с 2024 года. Пора уже внедрять его в свои проекты.

Первое место, где можно использовать элемент — это формы поиска. Но начну я с напоминания. Я уже рассказывал про нюансы вёрстки поиска в предыдущих частях. Советую сначала посмотреть их, чтобы лучше понять последующие примеры.

Для вёрстки области поиска нужно обернуть элементом search форму поиска.

<body>
  <search>
    <form class="search">
      <div class="field">
        <label for="search-field" class="field__label">Поиск</label>
        <input type="search" id="search-field" class="field__input">
      </div>
      <button class="search__button">Найти</button>
    </form>
  </search>
</body>

Проверим в скринридерах NVDA и JAWS нашу разметку. Начнём с первого.

А вот так разметку видит JAWS.

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

У многих интернет-магазинов есть фильтры. Я поговорил с Ильёй, и мы решили, что элемент search тоже пригодится в разметке этой области.

«Если вокруг много всего другого, то дополнительная подсказка будет полезна. Она важна для зонирования страницы. Плюс сгруппирует множество элементов, относящихся к фильтрам. Так будет проще не потеряться».

В общем, давайте добавим фильтры в предыдущий пример.

<body>
  <!-- элементы -->
  <search>
    <form class="search">
      <div class="field">
        <label for="search-field" class="field__label">Поиск</label>
        <input type="search" id="search-field" class="field__input">
      </div>
      <button class="search__button">Найти</button>
    </form>
  </search>

  <!-- элементы -->

  <search>
    <!-- не надо использовать элемент search для фильтров таким образом -->
    <form class="filters">
      <!-- разметка фильтров здесь -->
    </form>
  </search>
  <!-- элементы -->
</body>

Это не очень удачный пример. Скринридеры найдут два поиска на странице. Это запутает пользователей. Им придётся разбираться с назначением каждого поиска. Нужна дополнительная подсказка для второго элемента search.

Тем более, это просто сделать. Для элемента search можно применять атрибут aria-label. С помощью него мы зададим осмысленную подсказку.

<body>
  <!-- У меня сообщение. Я специально удалил первый поиск, чтобы легче было воспринимать код. -->
  <search aria-label="По товарам">
    <form class="filters">
      <!-- разметка фильтров здесь -->
    </form>
  </search>
</body>

В скринридере NVDA пользователи найдут наши фильтры в ориентирах.

В JAWS они будут находиться в режиме «Области документа».

Отдельно скажу о тексте подсказки. Я использую фразу «По товарам». Илья предлагал слово «Фильтры».

<body>
  <search aria-label="Фильтры">
    <form class="filters">
      <!-- разметка фильтров здесь -->
    </form>
  </search>
</body>

Мы не пришли к единому варианту. Но мы сошлись на том, что она не должна быть слишком длинной. Лучшего всего в одно слово. Если у вас есть идеи, то напишите, пожалуйста, их в комментариях.

Единицы измерения от вьюпорта и свойство font-size — не лучшая пара

Около восьми лет назад появилось техника «CSS-шлюзы». Или, проще говоря, стали рекомендовать автоматически рассчитывать размер текста, опираясь на размеры вьюпорта.

h1 {
  font-size: clamp(1rem, -0.875rem + 8.333333vw, 3.5rem);
}

Для демонстрации я нашёл демо Педро Родригеса.

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

Я с помощью изображений покажу несколько промежуточных состояний. Обратите внимание на значение font-size. Начнём с масштаба 100%.

Вот так браузеры отображают текст при масштабе 150%.

А вот так при масштабе 200%.

И это не ошибка. Так работают единицы измерения от вьюпорта. Для демонстрации объявим значение с помощью единицы измерения vw.

body {
  font-size: 10vw;
}

Вот такой размер текста будет при масштабе 100%. Обратите внимание на значение свойства font-size в инструментах разработчика.

А вот такой при масштабе 400%.

Значение становится меньше! Хотя я размеры вьюпорта не изменил. Для меня пока что это магия.

По этой причине я не люблю этот подход и не рекомендую его. Лучше старые добрые единицы измерения rem.

body {
  font-size: 3.5rem;
}

Вот так страница выглядит при масштабе 400%.

Значение свойства font-size осталось прежним. Но текст отлично увеличился без каких-либо проблем.

Кстати, если вы знаете, почему браузеры высчитывают единицы измерения от вьюпорта, напишите, пожалуйста, в комментариях. Мне интересно будет узнать. Спасибо!

Есть ли польза у элемента hr

У меня есть привычка лазить по сайтам и смотреть, как что сделано. Я частенько нахожу неожиданные решения. Бывает даже со знаком плюс. Но не в этот раз.

В общем, проинспектировал блок и увидел элемент hr.

В принципе, я не ожидал увидеть его в 2025 году. Но подумал, может, есть какой-то скрытый смысл. Возможно, ребята задумались о невизуальной доступности.

Скринридер озвучивает элемент с подсказкой «Разделитель». Я пошёл к Илье. Может, ему это решение понравится, но он тоже его не понял.

«В текущей реализации для меня подсказка бессмысленна. Не помогает, но и не вредит. Понять границу между текстом и ссылками можно без разделителя. Понять границу между ссылками и новой услугой можно тоже без разделителя. Для меня этот элемент относится к спаму».

Надеюсь, вы не используете элемент hr для декоративных штук. Да и вообще не используйте его. Это тот самый элемент, пользу которого мне назвать сложно.

У модальных окон должны быть заголовки

Модальные окна — очень важная часть интерфейсов. Привет фронтендерам, которые делают модалки внутри модалок! Извините, не мог остановить себя.

В общем, у модальных окон супер важная часть — их заголовок. Да-да, у модальных окон должен быть свой заголовок. Он помогает пользователям скринридера ориентироваться. Илья мне всё рассказал.

«Заголовок в модальном окне помогает понять, какие изменения произошли в интерфейсе. Ушёл ли я с текущей страницы в модальное окно или нет. Без него у меня не будет представления, где именно происходят изменения: в основном интерфейсе, где был до этого, или в новом».

Я разделяю модальные окна на два вида. У первых внутри есть заголовок. В этом случае мы можем связывать его с модальным окном с помощью атрибута aria-labelledby.

<body>
  <dialog class="modal" aria-labelledby="dialog_heading">
    <h2 id="dialog_heading">Подпишись на наши новости</h2>
    <!-- оставшиеся элементы модального окна -->
  </dialog>
</body>

Я тестировал код в скринридере NVDA. Он произносит так: «Диалог. Подпишись на наши новости».

Ко второму виду модальных окон я отношу окна без заголовков. В этом случае мы не можем использовать атрибут aria-labelledby, потому что его не с чем связывать. Здесь нам на выручку приходит атрибут aria-label.

<body>
  <dialog class="modal" aria-label="Подпишись на наши новости">
    <!-- элементы модального окна -->
  </dialog>
</body>

Результат такой же. Скринридер скажет: «Диалог. Подпишись на наши новости».

Заключение

В этой статье мы с Ильёй рассказали:

  • что элемент search отлично подходит для разметки областей поиска и фильтров;

  • единицы измерения от вьюпорта отключают у пользователя возможность масштабирать страницу;

  • элемент hr создаёт дополнительный «шум» для пользователя скринридера;

  • способы создать заголовок для модальных окон с помощью атрибутов aria-labelledby и aria-label.

На этом у нас всё. Спасибо за чтение!

P.S. Если вы хотите больше узнать о цифровой доступности, пишите мне в ТГ. Ссылка в профиле.

P.S.S. Все статьи серии доступны по тегу html_css_a11y_story_melnik909.

Комментарии (13)


  1. vanxant
    20.10.2025 19:19

    Тег <hr> нужен, эээ, как разделитель. Есть у вас скажем html-письмо (email), в нём есть текст и подпись. Вот hr между ними то что дохтур прописал.

    Аналогично, он мог бы смотреться уместно на странице типа главной хабра (разделяя поток анонсов разных статей)

    Аналогично, какие-нибудь стихи или анекдоты (кучей на одной странице)


    1. imalostshe
      20.10.2025 19:19

      <hr> - Разделительная линия


    1. ifap
      20.10.2025 19:19

      У автора похоже профдеформация: незрячим hr не нужен - значит, незачем его использовать вообще! Между тем это именно что декоративный визуальный разделитель и тут скорее вопрос к скринридеру, зачем он озвучивает визуальный чисто декоративный элемент?


      1. imalostshe
        20.10.2025 19:19

        HR-ов не уважает, возможно.


      1. melnik909 Автор
        20.10.2025 19:19

        Можете привести практичный пример пользы элемента hr?


        1. ifap
          20.10.2025 19:19

          Смотря что Вы называется практичным. Вот на иллюстрации в Вашей статье пример вполне нормальный - инфоблок отделяется чертой от блока действий. Прям практичный-практичный? Черта между статьей и сносками под ней.


          1. melnik909 Автор
            20.10.2025 19:19

            Спасибо. Еще вопрос. В чем польза черты в этом примере?


            1. ifap
              20.10.2025 19:19

              Визуальное разделение логических блоков. Графическому заголовку лет примерно столько же, сколько и книгоизданию.


              1. melnik909 Автор
                20.10.2025 19:19

                Вы сами сказали "визуальное разделение". HTML не про визуальную составляющую уже. Да, давно он был таким. Но эти времена уже прошли.

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


                1. ifap
                  20.10.2025 19:19

                  HTML про markup, т.е. разметку. Эта штуковина разметка и есть.


        1. PereslavlFoto
          20.10.2025 19:19

          Черта между текстом веб-страницы и подвалом, где находятся метаданные сайта.

          Черта между текстом веб-страницы и заголовком, где находится название сайта и меню навигации.


          1. melnik909 Автор
            20.10.2025 19:19

            Спасибо. Расскажите, пожалуйста, в чем польза черты в ваших примерах?


            1. PereslavlFoto
              20.10.2025 19:19

              Она служит разделителем.