HTML и CSS ошибки, влияющие на доступность. Мой опыт и моего незрячего знакомого Ильи. Часть 10

rkt0r42ghxzp6cjqumm-h0clbf8.jpeg

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

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

  • Почему в наших дизайн-системах и библиотеках есть сломанные нестандартные радиокнопки;
  • Мой способ отказаться от ссылки для изображения с сохранением интерактивности;
  • Дублирование стилей при наведении для фокуса вводит меня в ступор;
  • Можно ли скрыть кнопку с помощью атрибута disabled от скринридера.

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


▍ Как мы сломали нестандартные радиокнопки

Узнав о режиме высокой контрастности Windows, я первым делом протестировал свою библиотеку. И знаете, что увидел? Многие элементы сломались. Например, нестандартные радиокнопки.

Конечно, я вдохновлялся Codepen, когда создавал их. Большинство примеров вообще несовместимы с режимом высокой контрастности. Я пишу «большинство», потому что верю, что есть работающие правильно. Просто их не встретил.

Давайте посмотрим, что же нужно исправить. Я сделал скриншот из моей библиотеки.


qtgfcyymlklvga-p-ftsfylezgo.png

Среди элементов есть выделенный. Угадайте, какой из них он? Правильный ответ — первый. Вот доказательство в виде разметки.


  

Взглянем на стили компонента.

.toggle[type="radio"]::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  background-color: #242424;

  border-radius: 50%;
  opacity: 0;
  position: absolute;
  scale: 0;
}


Здесь оставшиеся стили радиокнопок
.toggle {
  appearance: none;
  margin: 0;
  width: 1rem;
  height: 1rem;

  border: 1px solid #242424;
  border-radius: 50%;
	
  display: grid;
  place-items: center;
}

.toggle[type="radio"]:checked::before {
  opacity: 1;
  scale: 1;
}

В режиме высокой контрастности Windows браузеры берут значения определённых свойств из настроек операционной системы. Для свойства background-color — из раздела «Фон».


q4s9e-ju1f1-a4yqxftsbwvbsg0.jpeg

В итоге получается, что у всех элементов со свойством background-color значение будет одним и тем же. По этой причине мы не увидим, какая радиокнопка выделена.

Починить компонент можно с помощью свойства border. Надо заменить им свойства width, height, background-color.

.toggle[type="radio"]::before {
  content: "";
  border: 0.25rem solid #242424;
  /* оставшиеся CSS */
}


tl0thy6smi1yzuwqddiaanqyt3y.png

Другое дело. Пожалуйста, проверьте радиокнопки в ваших библиотеках и дизайн-системах. Вдруг тоже нужно исправить.


▍ Свойство aspect-ratio помогает избавиться от дублирования ссылок

Ссылки вставляются везде. По надобности и без. Я уже писал, что дублировать одинаковые ссылки, мягко говоря, не помогают пользователям клавиатуры и скринридера. Возьмём обычный блок с картинкой и заголовком.


1gn-ui7-8koowsplibru7qdskqu.jpeg

В разметке у нас две ссылки. Одна для изображения, вторая для текста «Антон Миранчук уехал в Швейцарию! Всё о новом клубе и контракте россиянина». Обе ведут на одну и ту же страницу.

В итоге пользователь скринридера дважды услышит это. Мой путь, как пользователя клавиатуры, будет удлинён. А главное — без какой-либо пользы. Пожалуйста, старайтесь, так не делать. Рассмотрим альтернативный подход.

Для начала покажу разметку блока без лишних элементов.


  

Нам нужно отказаться от обёртки для изображения в виде ссылки с классом .top-article__img. Заменю её элементом

.


  

Я предлагаю использовать псевдо-элемент ::before для ссылки, который будет расположен над изображением. Так сохранится возможность перейти по ссылке, кликнув по изображению, и не будет двух ссылок.

Правда тут есть загвоздка. Как повторить размеры изображения? Мы знаем его ширину и высоту. Это поможет нам вычислить соотношение сторон. Понимаете, к чему я клоню? Да, свойство aspect-ratio здесь идеальный вариант.

Значение мы рассчитаем, поделив ширину изображения (269px) на высоту (160px). Итого получим 1.68. Позиционировать псевдо-элемент будем с помощью свойств left и bottom.

.top-article__title::before {
  content: "";
  position: absolute;
  width: 100%;
  aspect-ration: 1.68;
  bottom: 100%;
  left: 0;
}


lklsq0giugdmnobxzda5msmjr6i.jpeg

Этот способ я сам придумал. Как вам? Может есть минусы? Поделитесь, пожалуйста, в комментариях.


▍ Почему вам следует сохранить обводку с помощью свойства outline

Раньше у меня была привычка убирать стандартную обводку у кнопок и ссылок и дублировать стили при наведении для фокуса. Тогда я не знал, что создаю проблему. Давайте разберёмся, в чём дело.

Первое, на что следует обратить внимание — это режим высокой контрастности Windows. Обводка, созданная с помощью свойства outline, остаётся визуально заметной при переключении с помощи клавиши Tab. Это видно на примере ссылки.


  Ссылка №1
  Ссылка №2

.link:focus {
  outline: 4px solid;
}


p9gpimukezmgeyhjliqzdemc06m.png

А вот изменение других свойств — нет. Для демонстрации уберу свойство outline и добавлю свойство background-color в качестве альтернативы.

.link:focus {
  outline: none;
}

.link:is(:hover, :focus) {
  background-color: pink;	
}


-ajqsu18esa0hsr9vnrvm0-xqds.png

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

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

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

По этим причинам я прошу вас не убирать обводку. Лучше оставить её и свойство outline. Тем более, это можно сделать только для пользователей клавиатуры. Псевдо-класс :focus-visible никто не отменил.

Также сделайте форму обводки однообразной. Не заставляйте меня думать, почему она стала круглой. Большое спасибо.


▍ Доступна ли кнопка с атрибутом disabled для скринридеров?

Кнопки приходится использоваться часто в интерфейсах. И не только в формах. Многие переключатели следует делать с помощью них. Периодически требуется их скрыть до определённого момента.

Например, на сайте Купер в карусели есть кнопка для возврата назад.


jxdbunfa13ftnc0rfj6qwt0lzp8.png

Визуально она скрыта. При переключении с помощью клавиши Tab на неё нельзя попасть. Вроде всё отлично и нет никаких проблем. Это не так.

Посмотрим, как разработчики, скрыли элемент.


m2zwkobiehmstjs1hryzk5tb8sc.png

Мы видим свойство opacity. Я рассказывал подробно, что оно не скрывает элемент от скринридеров. Не буду повторяться. Я дальше покажу, к чему данный метод скрытия элемента привёл в нашем примере.

Напомню, что при переключении клавишей Tab элемент не попадается. Я стал думать, почему же так. В HTML я нашёл причину.


t-ss_pgp4eo4og1sxf2ujxjsis4.png

Атрибут disabled отключает интерактивность у элемента. Следовательно, на него нельзя попасть с помощью клавиши Tab. Но только пользователи скинридера кроме неё используют клавиши стрелки. Например, в этом случае скринридер NVDA прозносит: «Кнопка недоступна. Назад». Приехали.

Я думаю, что разработчики сайта сначала визуально скрыли кнопку с помощью свойства opacity. Потом они поняли, что она доступна с помощью клавиши Tab, и добавили атрибут disabled. На этом они остановились.

Не делайте, пожалуйста, так. Атрибут disabled не скрывает элемент. Скринридеры дадут понять пользователю, что она есть, но недоступна. Вот, что думает Илья:

«Сообщение скринридера, что кнопка вызывает недоумение. Я понимаю, что с элементом нельзя взаимодействовать. Но не ясно, к чему здесь мне это сообщение, потому что в примере некуда идти назад. Лучше бы вообще скрыть кнопку».

Разработчикам нужно было использовать свойство display со значением none, и убирать его по мере прокрутки элементов. В этом случае всё работало бы отлично.


▍ Заключение

С помощью этой статьи мы с Ильёй хотели призвать вас:

  • Не создавать дублирующие ссылки для изображений;
  • Починить нестандартные радиокнопки, чтобы ими можно было пользоваться;
  • Сохранить обводку при использовании клавиши Tab;
  • Не дублировать стили при наведении для фокуса;
  • Не скрывать от скринридеров интерактивные элементы с помощью атрибута disabled.

Оставлю ссылки на все выпуски:

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

© Habrahabr.ru