5 распространенных проблем с доступностью веб-приложений и способы их устранения

5 распространенных проблем с доступностью веб-приложений и способы их устранения

От автора: на протяжении многих лет я работал над различными крупными проектами веб-приложений с разработчиками разного уровня опыта и часто сталкивался с одними и теми же проблемами доступности веб-приложений. В этой статье я подробно расскажу о 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.