От автора: на протяжении многих лет я работал над различными крупными проектами веб-приложений с разработчиками разного уровня опыта и часто сталкивался с одними и теми же проблемами доступности веб-приложений. В этой статье я подробно расскажу о 5 наиболее распространенных проблемах с веб-доступностью, и предложу решения для них.
Делаете / делали ли вы эти ошибки в своих проектах?
1) Использование элемента ввода без связанной метки
Неправильно — Использование простого текста рядом с элементом ввода
Username <input type="text" name="username">
Текст «Username» не связан с input, поэтому, когда программа чтения с экрана объявляет input, она не сообщает, что он предназначен для ввода имени пользователя. input будет объявлен как “input, edit text”, поэтому пользователь программы чтения с экрана не будет иметь ни малейшего представления, для чего этот input, и что в него вводить.
Текст «Username» также не будет действовать как цель для нажатия / касания, чтобы установить фокус на input.
Неправильно — использовать метку, но не связывать ее с элементом ввода
<label>Username</label> <input type="text" name="username">
При использовании label он должен быть связан с соответствующим input. Это может быть сделано либо с помощью атрибута for или с помощью оборачивания input в label. Поскольку ни один из этих подходов здесь не использовался, label не связан с input.
Также обратите внимание, что label имеет конкретное семантическое значение, которое заключается в предоставлении метки для соответствующего input. label поэтому не должен быть использован для любого общего текстового содержимого, которое не действует в качестве метки для input. Я видел элементы label, используемые только для того, чтобы визуально выделить какой-то общий текст жирным шрифтом, что неправильно.
Неверно — используется метка с атрибутом for, но id отсутствует / неправильный
<label for="firstName">First name</label> <input type="text" name="firstName"> <label for="lastName">Last name</label> <input type="text" name="name" id="name">
Для “First name” input не содержит атрибута id, а для «Last name» элемент содержит атрибут id, но со значением name, а не lastName. В обоих случаях label неправильно связано с input.
Также обратите внимание, что значения атрибутов чувствительны к регистру, поэтому атрибут for=»Username» не будет соответствовать input с атрибутом id=»username».
Правильно — Использование метки и ввода с правильными значениями атрибутов for и id
<label for="username">Username</label> <input type="text" name="username" id="username">
Правильно – элемент ввода обернут в метку
<label> Username <input type="text" name="username"> </label>
Правильно — Использование атрибута aria-labelledby
<h2 id="resetHeading">Reset Password</h2> <span id="resetUsername">Username</span> <input type="text" name="username" aria-labelledby="resetHeading resetUsername">
Если существует один или несколько элементов, которые содержат текст, подходящий для использования в качестве метки для input, на идентификаторы этих элементов можно ссылаться с помощью атрибута aria-labelledby. В этом примере input будет объявлено следующее: “reset password username, edit text”.
Предоставление дополнительного контекста «reset password» может быть чрезвычайно полезным в некоторых сценариях, например, на странице регистрации, которая состоит из поля ввода имени пользователя в разделе для создания новой учетной записи и ввода имени пользователя в другом разделе для сброса пароля.
Правильно — Использование атрибута aria-label для невизуальной метки
<input type="text" name="searchTerm" aria-label="Search"> <button type="submit">Search</button>
В некоторых очень специфических случаях визуальная метка не требуется для input, поскольку цель input понятна из окружающего контента. В этом примере для зрячего пользователя ясно, для какой цели предназначен input, благодаря кнопке «Поиск» рядом с ним. Однако для пользователей программы чтения с экрана это визуальное соединение невозможно. Атрибут aria-label может быть использован для обеспечения невизуальных меток для input.
2) Использование шрифтов иконок без текстовой альтернативы
Шрифты иконок предоставляют удобный способ добавления масштабируемых, стилизованных иконок на веб-сайт (хотя теперь, возможно, SVG-иконки обеспечивают лучший подход). Разметка для отображения иконки обычно представляет собой тег <i> или span с примененным к нему классом, который включает в себя селектор :before или :after для вывода определенного символа Юникод. Этот символ Юникод визуально отображает иконку в файле шрифта, но программа чтения с экрана либо не объявляет этот символ, либо объявляет буквальное описание иконки. Ни первое, ни второе не является идеальным.
Имея это в виду, давайте рассмотрим некоторые распространенные проблемы доступности веб-сайтов при использовании шрифта иконок.
Неправильно — Иконка без текстовой альтернативы
<button> <i class="fas fa-download"></i> </button>
Неправильно — Скрытие текста в маленьких окнах просмотра
<style> .download-text { display: none; } @media screen and (min-width: 768px) { .download-text { display: inline; } } </style> <button> <span class="download-text">Download</span> <i class="fas fa-download"></i> <button>
Правильно — Иконка с текстовой альтернативой
<button> Download <i class="fas fa-download" aria-hidden="true"></i> <button>
Обратите внимание, что атрибут aria-hidden=»true» был применен к <i>, чтобы гарантировать, что программа чтения с экрана не объявляет символ Юникод.
Правильно — текстовая альтернатива все еще доступна, когда отображаемый текст скрыт в маленьких окнах просмотра
<style> .download-text { display: none; } @media screen and (min-width: 768px) { .download-text { display: inline; } } </style> <button> <span class="sr-only">Download</span> <span class="download-text" aria-hidden="true">Download</span> <i class="fas fa-download" aria-hidden="true"></i> </button>
Класс sr-only (только для средств чтения с экрана) был применен к первому , который размещает текст вне области просмотра, поэтому он не может быть видим, но все еще существует в DOM и объявляется средством чтения с экрана.
Как текст, отображаемый только в больших окнах просмотра, так и тег иконки <i> имеют атрибут aria-hidden=»true», поэтому не объявляются программой чтения с экрана.
3) Добавление обработчика кликов к неинтерактивному элементу
Неверно — добавление обработчиков кликов в div и span в React и Vue
<div onClick={this.addToBasket}>Add To Basket</div> <span @click="checkout">Checkout</span>
В отличие от нативного button или <a>, пользователь клавиатуры не может взаимодействовать и вызывать обработчики кликов для элементов div или span, а пользователь программы чтения с экрана не знает, что с элементами div или span можно взаимодействовать.
Правильно — использовать обработчики кликов с интерактивными элементами
<button onClick={this.addToBasket}>Add To Basket</button> <a href="#" @click="checkout">Checkout</a>
4) Не использование активной области для важной информации
С помощью прогрессивных веб-приложений, одностраничных приложений и клиентских веб-страниц с широкими возможностями содержимое веб-страницы может динамически изменяться без полной перезагрузки страницы. Когда содержимое части страницы динамически изменяется, зрячий пользователь может визуально увидеть эти изменения, но пользователь программы чтения с экрана не знает об этих изменениях.
Активные области обеспечивают возможность динамического изменения содержимого с объявлением программами чтения с экрана.
Неправильно — Важная информация не будет объявлена
<div>Your message has been sent</div> <span>Unable to place order as you're offline<span>
Правильно – Активная область используется для объявления важной информации
<div aria-live="polite" role="status"> Your message has been sent </div> <div aria-live="assertive"> Unable to place order as you're offline </div>
5) Не указание атрибута href для тега анкора
Неправильно — без атрибута href
<a onClick={this.upload}>Upload</a>
Неправильно — пустой атрибут href
<a href="" onClick={this.upload}>Upload</a>
Правильно — href атрибут указан со значением
<a href="#" onClick={this.upload}>Upload</a>
Источник: https://keepinguptodate.com
Редакция: Команда webformyself.