ARIA-атрибуты в компонентах выбора даты определяют доступность календаря для экранных дикторов и клавиатурной навигации, формируя корректную семантическую модель интерфейса поверх визуального представления. В контексте Pikaday ключевая задача ARIA — обеспечить интерпретацию всплывающего календаря как управляемого виджета с состояниями, фокусом и выбором элементов, а не как набора произвольных DOM-узлов.
Pikaday реализует календарь как всплывающий слой, связанный с текстовым полем ввода. С точки зрения доступности этот слой должен восприниматься как диалоговое окно или как всплывающий интерактивный компонент, управляемый через триггер.
Основные роли ARIA:
role="dialog" — обозначает контейнер календаря как
модальное или немодальное диалоговое окноrole="application" (используется реже) — указывает на
сложный интерактивный компонент с собственной логикой клавиатурыrole="grid" — календарная сетка дней месяцаrole="gridcell" — отдельная ячейка дняrole="button" — элементы управления переключением
месяцевИспользование role="grid" особенно важно, так как
календарь концептуально представляет таблицу с интерактивными ячейками,
где каждая ячейка обладает состоянием выбора.
Связывание текстового поля и всплывающего календаря реализуется через набор атрибутов, обеспечивающих контекст и управление:
aria-haspopup="dialog" — указывает, что поле открывает
всплывающий диалогaria-expanded="true|false" — отражает текущее состояние
открытия календаряaria-controls="pikaday-container" — связывает input с
контейнером календаряaria-label — задаёт доступное имя поля или
календаряТипичная структура связи:
<input
id="date-input"
aria-haspopup="dialog"
aria-expanded="false"
aria-controls="pikaday-calendar"
aria-label="Дата"
/>
<div id="pikaday-calendar" role="dialog" aria-modal="false">
...
</div>
Обновление aria-expanded синхронизируется с состоянием
открытия календаря. Это позволяет вспомогательным технологиям
отслеживать жизненный цикл компонента.
Pikaday реализует собственную систему навигации по дням месяца, что требует управления фокусом без перемещения реального DOM-фокуса на каждую ячейку.
Для этого применяется модель aria-activedescendant:
idПример:
<div
class="pika-single"
role="grid"
aria-activedescendant="pika-day-2026-06-15"
tabindex="0"
>
<div id="pika-day-2026-06-15" role="gridcell" aria-selected="true">
15
</div>
</div>
Такой подход уменьшает количество переключений фокуса и делает навигацию предсказуемой для assistive-технологий.
Каждая ячейка дня должна отражать своё состояние через ARIA:
aria-selected="true" — выбранная датаaria-disabled="true" — недоступная дата (например, вне
диапазона min/max)aria-current="date" — текущая дата (сегодня)aria-label — полное текстовое описание датыОсобое значение имеет aria-label, поскольку визуальное
представление даты (например, «15») недостаточно информативно.
Пример:
<div
id="pika-day-2026-06-15"
role="gridcell"
aria-selected="false"
aria-disabled="false"
aria-current="date"
aria-label="15 июня 2026"
>
15
</div>
Кнопки переключения месяцев требуют явного описания действия, так как их визуальное представление часто ограничено иконками.
Используемые атрибуты:
aria-label="Следующий месяц"aria-label="Предыдущий месяц"aria-controls="pikaday-calendar"Пример:
<button
class="pika-next"
aria-label="Следующий месяц"
aria-controls="pikaday-calendar"
>
›
</button>
Без этих атрибутов интерфейс становится недоступным для пользователей экранных дикторов, так как символы навигации не несут смысловой нагрузки.
Календарь Pikaday динамически обновляет содержимое при переключении
месяцев. Для корректного уведомления вспомогательных технологий
применяется aria-live:
aria-live="polite" — мягкое уведомление о смене
месяцаaria-atomic="true" — озвучивание полного блока при
обновленииПример контейнера заголовка месяца:
<div class="pika-title" aria-live="polite" aria-atomic="true">
Июнь 2026
</div>
Это обеспечивает корректное восприятие изменений без необходимости повторного фокуса на элементе.
Контейнер календаря должен быть доступен для клавиатурной навигации:
tabindex="0" — включение контейнера в порядок
фокусаtabindex="-1" — исключение вспомогательных элементов из
табуляцииОсновной фокус обычно удерживается на grid-контейнере:
<div class="pika-single" role="grid" tabindex="0">
...
</div>
Отдельные дни не получают tabindex, поскольку навигация
реализуется стрелками клавиатуры внутри grid-модели.
Когда календарь закрыт, он должен быть исключён из дерева доступности:
aria-hidden="true" — скрытие закрытого календаря<div id="pikaday-calendar" role="dialog" aria-hidden="true">
При открытии значение переключается:
aria-hidden="false"
Это предотвращает ситуацию, когда скрытый календарь остаётся доступным для экранного диктора.
В некоторых реализациях Pikaday используется модель кнопок вместо
gridcell. В этом случае применим aria-pressed:
aria-pressed="true" — активная кнопка датыaria-pressed="false" — неактивнаяОднако grid-модель предпочтительнее, так как она семантически ближе к таблице календаря.
Для объединения частей календаря используются связи:
aria-labelledby — связывает заголовок месяца с
контейнеромaria-describedby — добавляет дополнительное
описаниеПример:
<div id="pika-header" class="pika-title">
Июнь 2026
</div>
<div
class="pika-single"
role="grid"
aria-labelledby="pika-header"
>
Это создаёт логическую связь между визуальным заголовком и структурой календаря.
При использовании ограничений minDate и
maxDate каждая неактивная дата должна отражать
недоступность:
aria-disabled="true"aria-selected="true"Дополнительно может использоваться aria-label,
уточняющий причину:
aria-label="10 июня 2026, недоступно"
Такое уточнение повышает информативность без изменения визуального интерфейса.
ARIA-структура должна соответствовать логике клавиатурного управления:
aria-activedescendantaria-selectedaria-expanded="false"Несоответствие между состоянием ARIA и фактической логикой приводит к нарушению доступности: экранный диктор начинает озвучивать устаревшие состояния интерфейса.
Комплексная модель включает:
role="dialog" для контейнераrole="grid" для календарной сеткиrole="gridcell" для днейaria-selected, aria-disabled,
aria-current для состоянийaria-activedescendant для управления фокусомaria-expanded, aria-controls для связи с
inputaria-live для динамических обновленийaria-label для семантического описания элементовСогласованное применение этих атрибутов формирует доступный интерфейс календаря, в котором визуальная структура и семантическая модель остаются синхронизированными на всех уровнях взаимодействия.