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

от автора

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

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

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

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

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

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

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

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

Две радиокнопки. Обе отображаются одинаково без кружка в середине

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

<body>   <div class="custom-radio-button">     <input id="сrb-1" class="toggle" type="radio" name="radio" checked>     <label for="сrb-1" class="custom-radio-button__label">Вариант №1</label>   </div>   <div class="custom-radio-button">     <input id="сrb-2" class="toggle" type="radio" name="radio">     <label for="сrb-2" class="custom-radio-button__label">Вариант №2</label>   </div> </body> 

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

.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 — из раздела «Фон».

Окно с настройками операционной системы. Можно задать цвет фона, текста, ссылки, неактивного текста, выделенного текста, текста у кнопки. Я выбрал задать цвет фона. Отображается элемент для выбора цвета. В поле уже выбран цвет 202020

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

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

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

Две радиокнопки. У первой есть в середине кружок, у второй его нет

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

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

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

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

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

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

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

<body>   <div class="top-article _small">     <a href="article-5699252.html" class="top-article__img">       <!-- здесь изображение -->     </a>     <div class="top-article__info">       <a href="article-5699252.html" class="top-article__title">         Антон Миранчук уехал в Швейцарию! Всё о новом клубе и контракте россиянина       </a>       <!-- здесь блок с временем публикации и с счётчиком комментариев -->     </div>   </div> </body> 

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

<body>   <div class="top-article _small">     <div class="top-article__img">       <!-- здесь изображение -->     </div>     <div class="top-article__info">       <a href="article-5699252.html" class="top-article__title">         Антон Миранчук уехал в Швейцарию! Всё о новом клубе и контракте россиянина       </a>       <!-- здесь блок с временем публикации и с счётчиком комментариев -->     </div>   </div> </body> 

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

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

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

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

Псевдоэлемент отображен поверх превью

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

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

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

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

<body>   <a href="#0" class="link">Ссылка №1</a>   <a href="#0" class="link">Ссылка №2</a> </body> 

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

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

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

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

Две ссылки. На первую ссылку сфокусировались, поэтому применились стили для состояния. Внешне ссылки одинаковые

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

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

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

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

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

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

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

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

Интерфейс Купер. С помощью инструментов разработчика показываю кнопку

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

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

В инструментах разработчика показываю, свойство opacity со значением 0

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

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

В инструментах разработчика показываю атрибут disabled у кнопки

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

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

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

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

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

▍ Заключение

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

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

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

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


ссылка на оригинал статьи https://habr.com/ru/articles/845112/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *