Статьи

Поддержка WAI-ARIA для виджета автозаполнения

В этом посте я хотел бы обсудить доступность для виджета автозаполнения. Обычно виджет автозаполнения предоставляет подсказки при вводе в поле. В своей текущей работе я реализовал компонент JSF на основе Twitter Typeahead — гибкой библиотеки JavaScript, которая обеспечивает прочную основу для создания надежных заголовков. Виджет Typeahead имеет четкую спецификацию в форме псевдокода, в которой подробно описывается, как пользовательский интерфейс реагирует на события. Typeahed может показывать подсказку в соответствующем поле ввода, как это показывает поле поиска в Google, выделять совпадения, работать с настраиваемыми наборами данных и предварительно скомпилированным шаблоном. Кроме того, механизм предложений Bloodhound предлагает предварительную выборку, интеллектуальное кэширование, быстрый поиск и обратную засыпку удаленными данными.

машинописный

Несмотря на многие особенности, одним большим недостатком Typeahead является недостаточная поддержка WAI-ARIA (я бы сказал, что до сих пор ее полностью не было). Виджет автозаполнения должен быть спроектирован так, чтобы быть доступным сразу после установки пользователям программ чтения с экрана и других вспомогательных инструментов. Я решил добавить полностью поддержку WAI-ARIA, сделал это и отправил свой запрос на отправку в GitHub. Ниже приведена новая разметка «WAI-ARIA осведомлена» с пояснением (не релевантные атрибуты HTML опущены).

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<input class="typeahead tt-hint" aria-hidden="true">
 
<input class="typeahead tt-input" role="combobox"
    aria-autocomplete="list/both"
    aria-owns="someUniqueID"
    aria-activedescendant="set dynamically to someUniqueID-1, etc."
    aria-expanded="false/true">
   
<span id="someUniqueID" class="tt-dropdown-menu" role="listbox">
    <div class="tt-dataset-somename" role="presentation">
        ...
        <span class="tt-suggestions" role="presentation">
            <div id="someUniqueID-1" class="tt-suggestion" role="option">
                ... single suggestion ...
            </div>
            ...
        </span>
        ...
    </div>
</span>
 
<span class="tt-status" role="status" aria-live="polite" style="border:0 none; clip:rect(0, 0, 0, 0); height:1px;
      width:1px; margin:-1px; overflow:hidden; padding:0; position:absolute;">
      ... HTML string or a precompiled template ...
</span>

Первое поле ввода с классом tt-hint имитирует визуальную подсказку (см. Рисунок выше). Подсказка завершает входной запрос к согласованному предложению визуально. Запрос может быть выполнен с предложением (подсказкой) нажатием стрелки вправо или клавиши табуляции. Подсказка не относится к программам чтения с экрана, поэтому мы можем применить aria-hidden = ”true” к этому полю. Подсказка игнорируется программами чтения с экрана. Почему это не важно? Потому что мы заставим читать совпавшее предложение более разумным в области «status» с помощью aria-live = »ежный »(будет объяснено ниже).

Следующее поле ввода — это основной элемент, в который пользователь вводит запрос. Это должно иметь роль = ”combobox”. Это рекомендуемая роль для автозаполнения. См. Официальный документ WAI-ARIA для более подробной информации. Фактически, документ также показывает грубую структуру разметки автозаполнения!

Основное поле ввода должно иметь различные состояния и свойства ARIA. aria-autocomplete = ”list” указывает, что входные данные предоставляют предложения автозаполнения в виде списка по мере ввода пользователем. aria-autocomplete = ”both” указывает, что предложения также предоставляются подсказкой (в дополнение к списку). Свойство aria-owns указывает, что между полем ввода и списком с предложениями существует отношение родитель / потомок. Это свойство должно всегда устанавливаться, когда иерархия DOM не может использоваться для представления взаимосвязи. В противном случае программы чтения с экрана получат проблему, чтобы найти список с предложениями. В нашем случае это указывает на идентификатор списка. Самое интересное свойство — это aria-activedescendant. Невидимый пользователь перемещается по списку с помощью клавиш со стрелками. Свойство aria-activedescendant распространяет изменения в фокусе на вспомогательные технологии — оно настраивается для отражения атрибута ID текущего дочернего элемента, к которому был проведен переход. На картинке выше выделен пункт «Лоуренс Аравийский». aria-activedescendant настроен на идентификатор этого элемента, и программы чтения с экрана читают для слепых пользователей «Лоуренс Аравийский». Примечание: фокус остается на поле ввода, так что вы все еще можете редактировать значение ввода. Я предлагаю прочитать больше об этом свойстве в Google Введение в веб-доступность .

автозаполнения привод аннотированный обновляемый

Свойство aria-extended указывает, является ли список с предложениями расширенным (true) или свернутым (false). Это свойство будет обновляться автоматически при изменении состояния списка.

Список с предложениями должен иметь роль «список». Это означает, что виджет позволяет пользователю выбирать один или несколько элементов из списка вариантов. роль = ”опция” должна применяться к отдельным узлам элемента результата в списке. Есть интересная статья «Используйте роли« listbox »и« option »при построении списков автозаполнения» , которую я предлагаю прочитать. Не важные для экранных ридеров части должны быть помечены ролью = «презентация» Эта роль гласит: «Моя разметка только для невидимых пользователей». Вы, наверное, спросите, что насчет роли = «приложение»? Это важно для нас? На самом деле, нет. Я пропустил его после прочтения «Не все виджеты ARIA заслуживают роль =« приложение »» .

Последний элемент в разметке — это span с ролью = «status» и свойством aria-live = «polite». Для чего это хорошо? Вы можете оживить свой виджет, сообщив пользователю, что результаты автозаполнения доступны через текст, который автоматически произносится. Текст для произнесения должен быть добавлен виджетом к элементу, который перемещен за пределы области просмотра. Это упомянутый элемент span с примененными стилями. Стили в точности соответствуют CSS-классу jQuery ui-helper-hidden-available, который скрывает контент визуально, но оставляет его доступным для вспомогательных технологий. Свойство aria-live = ”polite” в элементе span означает, что обновления в этом элементе должны быть объявлены в следующем изящном интервале, например, когда пользователь перестает печатать. Как правило, свойство aria-live указывает на раздел внутри контента, который является живым, и многословность, в которой должны быть объявлены изменения. Я определил устный текст для автозаполнения в своем проекте как шаблон JavaScript, скомпилированный с помощью Handlebars (можно использовать любой другой шаблонизатор, такой как Hogan ).

1
2
3
4
Handlebars.compile(
    '{{#unless isEmpty}}{{count}} suggestions available.' +
    '{{#if withHint}}Top suggestion {{hint}} can be chosen by right arrow or tab key.' +
    '{{/if}}{{/unless}}')

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

Последнее, но не менее важное — это тестирование. Если у вас еще не установлена ​​программа чтения с экрана, установите расширения Google Chrome ChromeVox и Accessibility Developer Tools . Это хорошие инструменты для развития. Пожалуйста, посмотрите короткую демонстрацию ChromeVox и демо-версию для Accessibility Developer Tools тоже. Альтернативно, вы также можете попробовать бесплатную автономную программу чтения с экрана NVDA . Просто попробуйте инструменты.