Статьи

Написание JavaScript с доступностью в мыслях

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

Эта статья была первоначально опубликована на Medium .

В своем первом посте « Написание HTML с учетом доступности» я объяснил, почему и как я начал с доступности веб-страниц. Я также поделился некоторыми советами о том, как улучшить разметку, чтобы сделать ваши сайты более доступными. Некоторые из них были довольно простыми, но, тем не менее, ценными. Все сводится к двум самым важным неписаным правилам в разработке интерфейса: изучите основы и потратьте достаточно времени на планирование и написание HTML . И вы, и ваши пользователи получат пользу от чистой и семантической разметки.

К счастью, HTML — не единственный язык, который нам нужен для создания веб-сайтов, но чем сложнее язык, тем проще могут быть проблемы и JavaScript может стать очень сложным. Несмотря на то, что наш код работает с контентом, легко забыть о пользователях с другими устройствами ввода, кроме мыши или сенсорной панели, например, пользователей клавиатуры или программы чтения с экрана. Во второй статье из четырех о веб-доступности я собрал несколько советов о том, что следует учитывать при написании JavaScript и как сделать ваши компоненты JavaScript более доступными.

JavaScript не враг

Доступность JavaScript

Прежде чем читать мои советы, я хочу отметить одну важную вещь — создание доступного сайта не означает, что вы должны решить, использовать JavaScript или нет. Доступность заключается в том, чтобы сделать контент доступным как можно большему числу людей, включая пользователей со старыми браузерами и компьютерами, медленным интернет-соединением, строгими ограничениями безопасности (например, без JavaScript) и так далее. Опыт работы в таких условиях, когда JavaScript может не работать или загружаться слишком долго, может быть не идеальным, но все же достаточно хорошим, если веб-сайт доступен и пригоден для использования.

Если JavaScript исполняемый, его можно использовать даже для улучшения доступности. Сара Соуэйдан написала о своем опыте создания виджета всплывающей подсказки в разделе Создание всплывающей подсказки справки … сложнее, чем я думала . Она объясняет, как «каждое отдельное решение без JS имело очень серьезные недостатки, которые негативно влияли на пользовательский опыт», и почему JavaScript важен для доступности.

Марко Зеэ много писал о JavaScript и доступности в своей статье. JavaScript не враг доступности! Я настоятельно рекомендую вам прочитать его пост.

Но хватит вступительного разговора! Давайте доберемся до этого …

Отличное управление фокусом необходимо

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

Навигация по сайту с помощью клавиатуры означает переход с одного фокусируемого элемента на другой в порядке DOM. Обычно это достигается с помощью клавиши Tab или Shift + Tab для обратного направления. Фокусируемые элементы — это, помимо прочего, ссылки, кнопки и элементы формы . Их можно выбрать клавишей Enter и иногда пробелом . Будучи сфокусированными и выбираемыми различными способами, они имеют очень полезные функции по умолчанию. Поэтому имеет смысл использовать правильные семантические элементы и писать HTML в логическом порядке.

Такие элементы, как <p><h2><div> Мы часто используем подобные теги для создания пользовательских компонентов на основе JavaScript, что может быть проблематично для пользователей клавиатуры.

Делаем не фокусируемые элементы фокусируемыми

Можно сфокусировать нефокусируемые элементы, добавив атрибут tabindex с целочисленным значением. Если значение установлено в 0 Если значение является отрицательным числом, элемент является программно фокусируемым (например, с помощью JavaScript), но недоступен через клавиатуру. Вы также можете использовать значение больше 0антишаблоном .

 <h2 tabindex="0">A focusable heading</h2>

Если вы хотите узнать больше о tabindexУправление фокусом с помощью tabindex » Роба Додсона .

Фокусировка элементов с помощью JavaScript

Даже если элементы являются фокусируемыми, иногда они не в правильном порядке DOM. Чтобы проиллюстрировать это, я создал простой компонент модального окна в HTML, CSS и JS ( демо и редактируемый Pen ).

Если вы используете клавишу Tab, чтобы перейти к кнопке и нажать Enter , появится модальное окно. Если вы нажмете клавишу Tab еще раз, фокус перейдет к следующей ссылке визуально под модальным окном. Ожидаемое поведение — следующий сфокусированный элемент находится внутри модального окна. Но это не потому, что элементы ориентированы в DOM-порядке, а модальное окно расположено внизу документа. Вы можете увидеть это в действии на этом экране записи .

Чтобы это исправить, нужно сделать фокусируемое модальное окно, а затем сфокусировать его с помощью JavaScript.

 <div class="modal" id="modal2" tabindex="0">
  ...
</div>
 function showModal() {
  var modal = document.getElementById('modal2');
  modal.focus();
  ...
}

Вы можете увидеть это в действии в обновленном примере ( демо и редактируемое перо ), нажав на кнопку, нажав Enter и снова вставив вкладку. Вы увидите, что само модальное окно теперь сфокусировано.

Это здорово, но здесь есть еще две проблемы.

Если вы закроете модальное окно нажатием Esc, фокус будет потерян. В идеале фокус должен был вернуться назад к кнопке, на которой он находился до открытия модального окна. Чтобы добиться этого, вы должны сохранить последний сфокусированный элемент в переменной.

Мы можем использовать document.activeElement

 var lastFocusedElement;

function showModal() {
  lastFocusedElement = document.activeElement;

  var modal = document.getElementById(modalID);
  modal.focus();
  ...
}

Теперь, когда у вас есть ссылка на кнопку, вы можете снова сфокусировать ее, когда модальное окно закрыто.

 function removeModal() {
  ...
  lastFocusedElement.focus();
}

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

Рекомендуется сохранять фокус в модальном окне, когда оно открыто. Прямо сейчас все еще возможно выйти из модального. Я не буду вдаваться в подробности, но для полноты картины я создал четвертое перо с так называемой клавиатурной ловушкой ( демо и редактируемое перо ). Фокус будет оставаться в модальном окне до тех пор, пока он активен, как видно на этом экране записи .

Если вы сравните первое и последнее перо, вы увидите, что лишнего кода не так много. Возможно, он не идеален, но окончательное решение гораздо приятнее в использовании.

Есть еще один пример доступного мода и отличная статья под названием « Использование tabindex» от людей из Google. Если вы хотите узнать больше о тестировании клавиатуры, посетите веб-сайт WebAIM . Они предоставляют список «наиболее распространенных интерактивных взаимодействий, стандартных нажатий клавиш для взаимодействия и дополнительную информацию о том, что следует учитывать во время тестирования».

Дополнительные примеры управления фокусом можно найти в видео egghead.io « Управление фокусом» с использованием CSS, HTML и JavaScript от Marcy Sutton или в эпизоде ​​A11ycasts Что такое Focus? Роб Додсон.

Если вам нужна кнопка, используйте элемент <button>

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

Я сделал Pen ( режим отладки / Pen with code ), чтобы проиллюстрировать некоторые проблемы использования <span><div><button><input> Если вы перейдете по странице, вы увидите, что вы можете фокусировать первую кнопку, но не вторую. Причина этого, конечно, в том, что первая кнопка — это <button><div> Вы можете обойти эту проблему, добавив tabindex="0"<div> Вот почему третья и четвертая кнопки являются фокусируемыми, даже если они <div>

 <!-- Button and focusable -->
<button class="btn">I'm a button</button>

<!-- Div and not focusable -->
<div class="btn">I'm a div</div>

<!-- Still just a div, but focusable -->
<div class="btn" tabindex="0">I'm a div</div>

<!-- Button role and focusable -->
<div class="btn" tabindex="0" role="button">I'm a div</div>

Кнопка div действительно фокусируема, но все еще ведет себя как <div>rolebutton Чтобы проиллюстрировать это, я добавил простой обработчик события click для всех элементов .btnPen ). Если вы нажмете кнопки, появится окно с предупреждением, но если вы попытаетесь сделать то же самое с помощью клавиш ( Enter или пробел ), только первая кнопка вызовет событие. Вам нужно было бы добавить обработчик событий клавиш к кнопкам div, чтобы полностью имитировать поведение кнопок по умолчанию, что кажется ненужным, не так ли? Вот почему вы должны использовать элемент <button>

Посмотрите эпизод A11ycasts «Просто используйте кнопку» Роба Додсона или прочитайте Ссылки, Кнопки, Представления и Дивы, О, черт возьми , Адриана Розелли для получения дополнительной информации и примеров.

Пользователи программы чтения с экрана должны быть проинформированы о динамическом изменении содержимого

Обычно программы чтения с экрана объявляют контент только тогда, когда элемент находится в фокусе, или пользователь использует собственные команды навигации программы чтения с экрана. Если контент загружается динамически и вставляется в DOM, только зрячие пользователи будут знать об изменениях. ARIA Live Regions предоставляет несколько вариантов решения этой проблемы. Я покажу вам, как в примере.

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

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

 <div class="message" role="status">Changes saved!</div>

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

Будьте вежливы с вашими пользователями

Разница между statusalertalert Напротив, status

Есть еще один атрибут, называемый aria-liveoffpoliteassertive Из этих трех значением offaria-live="polite"role="status"aria-live="assertive"role="alert" В некоторых хорошо известных предопределенных случаях лучше использовать конкретную предоставленную роль живого региона . Также, если браузер не поддерживает role Леони Уотсон поделилась некоторыми результатами тестирования поддержки чтения с экрана для регионов ARIA .

 <div role="alert" aria-live="assertive"></div>

Иногда имеет смысл объявить больше, чем просто содержание, которое изменилось

По умолчанию программы чтения с экрана представляют только измененный контент, даже если в том же регионе прямой трансляции есть другой контент, но иногда имеет смысл объявить весь текст. Поведение по умолчанию можно изменить с помощью атрибута aria-atomic Если вы установите значение true

Пол Дж.Адам ( Paul J. Adam) демонстрирует демонстрационный пример арии-атома, в котором сравниваются различные параметры региона. Он также протестировал свою демонстрацию с VoiceOver на iOS 8.1 и записал ее, чтобы вы могли увидеть ее в действии. Я предлагаю вам посмотреть запись ( VoiceOver iOS 8.1, говорящие символы, остающиеся относящимися к aria и относящиеся к aria в регионах с живыми ариями ), если вы хотите лучше понять возможные варианты использования aria-atomic

Некоторые вещи для рассмотрения

  • Живые регионы не перемещают фокус, они просто вызывают объявление текста
  • Используйте alert status
  • Избегайте создания предупреждений, которые исчезают автоматически, потому что они могут исчезать слишком быстро.
  • Во время моих тестов у меня были проблемы с VoiceOver. Скрытие оповещения с помощью CSS или его динамическое создание не всегда работали. Убедитесь, что вы тщательно протестировали свои живые регионы в разных браузерах с различным программным обеспечением.

Конечно, есть оповещения эпизода A11ycasts ! Роб Додсон для более подробной информации и примеров. У Гейдона Пикеринга есть другой пример для живых регионов в его коллекции примеров ARIA.

Вам не нужно угадывать, какие шаблоны использования должны обеспечивать ваши виджеты

Часто трудно представить себе все функции, которые должен обеспечивать виджет с точки зрения навигации и доступности. Рад, что есть ресурс под названием WAI-ARIA Authoring Practices 1.1, который помогает нам в этом. WAI-ARIA Authoring Practices — руководство по пониманию того, как использовать WAI-ARIA для создания доступного многофункционального интернет-приложения. Он описывает рекомендуемые шаблоны использования WAI-ARIA и дает представление о концепциях, лежащих в их основе.

У них есть руководства по созданию аккордеонов, слайдеров, вкладок и многого другого.

Доступные компоненты JavaScript

Есть несколько отличных ресурсов для доступных компонентов JavaScript:

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

резюмировать

Используйте преимущества JavaScript, чтобы улучшить доступность вашего сайта. Позаботьтесь об управлении фокусом, узнайте об общих шаблонах использования и учитывайте пользователей программы чтения с экрана, когда вы манипулируете DOM. Прежде всего, не забывайте, для кого вы делаете веб-сайты, и получайте удовольствие от этого.

Выходя за пределы

Это все на данный момент. Я надеюсь, что эти советы помогут вам написать более доступный HTML и JavaScript. Большое спасибо Хейдону Пикерингу, потому что его книга « Inclusive Front-End Designs Patterns» является основой большинства материалов, которые вы только что прочитали. Если вы хотите узнать больше о доступности и инклюзивном дизайне, я настоятельно рекомендую вам прочитать его книгу.

Особая благодарность Адриану Розелли за помощь в написании этой статьи и Еве за то, что вычитали мою статью.

Ресурсы

Это список всех ресурсов, связанных с этой статьей.