Использование Javascript для улучшения доступности форм с помощью Aria Labels
Почему важно формировать доступность
Веб-формы являются одними из наиболее распространенных и важных компонентов цифрового опыта. Они обеспечивают работу страниц входа в систему, потоков оформления заказа, представлений опросов, запросов на контакт и бесчисленных других взаимодействий. Для пользователей с визуальными, двигательными или когнитивными нарушениями плохо построенная форма может быть непреодолимым барьером. Доступность - обеспечение того, что все пользователи могут воспринимать, понимать, ориентироваться и взаимодействовать с формами - это не просто этические обязательства; это юридическое требование во многих юрисдикциях и практическое преимущество бизнеса, которое расширяет охват аудитории и снижает затраты на поддержку.
Вспомогательные технологии, такие как устройства чтения экрана, программное обеспечение распознавания голоса и коммутаторы, полагаются на хорошо структурированный семантический HTML и правильно применяемые атрибуты ARIA (Доступные богатые интернет-приложения), чтобы передать элементы управления формой, их цели и текущие состояния. Без этих сигналов пользователи могут столкнуться с отсутствующими или запутанными ярлыками, не знать о необходимых полях, не понимать ошибки проверки или быть неспособными завершить представления.
В этой статье рассматривается, как JavaScript может быть использован для повышения доступности форм посредством динамического применения и управления метками ARIA. Мы рассмотрим основные атрибуты ARIA для форм, пройдемся по реальным шаблонам JavaScript для улучшения ясности метки, связи с ошибками и обновлений живой области и предоставим примеры кода, которые можно адаптировать немедленно. К концу вы поймете, как сочетать методы JavaScript с ARIA для создания форм, которые являются надежными, реактивными и инклюзивными.
Понимание ярлыков ARIA и их роли в формах
ARIA предоставляет набор атрибутов, которые дополняют HTML для улучшения доступности динамического контента и сложных элементов управления пользовательским интерфейсом. Для форм наиболее важными атрибутами являются:
- — Предоставляет явное, доступное имя для элемента, когда отсутствует видимая метка. Например, ввод поиска без видимой может использовать .
- — Ссылки на один или несколько существующих элементов по ID для составления доступного имени. Это полезно, когда видимая метка существует, но не связана программно (например, заголовок или пролет).
- — указывает на элемент, который обеспечивает более длинное описание, например, текст подсказки или сообщение об ошибке.
- — Указывает, что вход должен иметь значение до того, как форма может быть представлена.В сочетании с на родных входах HTML5 это обеспечивает избыточность для более старых вспомогательных технологий.
- — Показывает, что значение поля не удовлетворяет правилам валидации.Это состояние часто устанавливается и обновляется динамически через JavaScript.
- — Идентифицирует элемент, содержащий сообщение об ошибке для конкретного поля, позволяя считывателям экрана связать ошибку непосредственно с управлением.
Эти атрибуты не меняют визуального облика формы; они влияют только на то, как вспомогательные технологии интерпретируют и объявляют элементы.Правильное их использование является краеугольным камнем доступного дизайна формы.
Когда нативного HTML недостаточно: необходимость в JavaScript
Только HTML может создавать доступные формы: используя элементы с атрибутами , , и для группировки, и нативную валидацию с и .
- Формы, которые построены или изменены на стороне клиента (например, одностраничные приложения).
- Условные поля, которые появляются или исчезают на основе выбора пользователя.
- Пользовательские элементы формы (например, пользовательские галочки, выберите коробки), которые теряют нативную доступность.
- Обратная связь проверки в реальном времени, которая обновляет сообщения об ошибках без перезагрузки страницы.
- Многошаговые или волшебные формы, в которых необходимо управлять фокусом и анонсировать изменения контекста.
JavaScript устраняет эти пробелы, программно назначая, обновляя и удаляя атрибуты ARIA, поскольку пользователь взаимодействует с интерфейсом. Это гарантирует, что пользователи вспомогательных технологий получают ту же информацию и сигналы, что и зрячие пользователи.
Основные шаблоны: использование JavaScript для добавления и обновления ярлыков ARIA
Шаблон 1: Присвоение вводимым данным без видимых ярлыков
Иногда ограничения визуального дизайна означают, что маркировка ввода видимым текстом непрактична. В этих случаях предоставляет доступное имя. Простейший подход заключается в том, чтобы добавить его непосредственно в HTML, но когда форма генерируется динамически компонентами JavaScript или извлекается из API, вы можете вставить его после создания элемента.
// After a dynamic input is created or added to the DOM
const searchInput = document.querySelector('.search-field');
if (searchInput) {
searchInput.setAttribute('aria-label', 'Search website');
}
Избегать дублирования информации: если видимая метка присутствует, но не связана с или вложении, рассмотрите возможность использования вместо этого, чтобы избежать избыточности. W3C ARIA Спецификация содержит рекомендации о том, когда каждый атрибут является подходящим.
Шаблон 2: Укрепление ассоциации с этикетками
Если группа элементов (например, радиокнопки) описывается видимым заголовком, вы можете ссылаться на этот заголовок из каждого управления. JavaScript может использоваться для сбора идентификатора заголовка и применения атрибута ко всем соответствующим входам.
const groupHeading = document.getElementById('shipping-options-heading');
if (groupHeading) {
const radioButtons = document.querySelectorAll('input[name="shipping"]');
radioButtons.forEach(radio => {
radio.setAttribute('aria-labelledby', groupHeading.id);
});
}
Это более надежно, чем использование , потому что он повторно использует существующий видимый контент, что выгодно пользователям, которые полагаются на пользовательские настройки текста или настройки вербозита считывателя экрана.
Паттерн 3: Объявления о динамических изменениях в реальном регионе
Когда содержимое формы изменяется без полной загрузки страницы, например, отображение поля кода скидки после тикания флажка, пользователи считывающего экрана могут не знать о новом контенте. Объединив области с JavaScript, вы можете объявить об этих изменениях.
const toggle = document.getElementById('promo-toggle');
const promoContainer = document.getElementById('promo-code-container');
promoContainer.setAttribute('aria-live', 'polite');
toggle.addEventListener('change', function () {
if (this.checked) {
promoContainer.classList.remove('hidden');
promoContainer.innerHTML = `
<label for="promo-code">Enter promo code</label>
<input type="text" id="promo-code">
`;
document.getElementById('promo-code').setAttribute('aria-label', 'Promotion code');
} else {
promoContainer.classList.add('hidden');
promoContainer.innerHTML = '';
}
});
Обратите внимание, что регионы лучше всего подходят для простых объявлений; для большего контроля рассмотрите возможность использования выделенного элемента «живой» области, который вы обновляете вручную.
Динамическая валидация и коммуникация с ошибками
Одним из наиболее эффективных применений JavaScript в доступных формах является обработка ошибок проверки.WCAG Success Criterion 3.3.1 (Error Identification) требует, чтобы любая ошибка ввода была описана в тексте пользователю. атрибуты ARIA, такие как и , являются ключом к удовлетворению этого требования динамически.
[[28]] Ошибка в подтверждении
Когда поле формы не валидируется (либо нативное, либо пользовательское), установите и удалите его (или установите ), когда ошибка исправлена.
const emailInput = document.getElementById('email');
function validateEmail(value) {
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
emailInput.setAttribute('aria-invalid', !isValid);
return isValid;
}
emailInput.addEventListener('blur', function () {
validateEmail(this.value);
});
Связывание сообщений об ошибках с и
Текст ошибки должен быть программно связан с полем. Используйте , чтобы указать на контейнер сообщения, или для более нового, более точного атрибута. Следующий пример создает промежуток ошибок и прикрепляет его к полю.
const emailInput = document.getElementById('email');
const errorContainer = document.getElementById('email-error');
emailInput.addEventListener('invalid', function (event) {
event.preventDefault(); // prevent native popup
this.setAttribute('aria-invalid', 'true');
this.setAttribute('aria-describedby', 'email-error');
errorContainer.textContent = 'Please enter a valid email address.';
errorContainer.style.display = 'block';
});
emailInput.addEventListener('input', function () {
if (this.validity.valid) {
this.setAttribute('aria-invalid', 'false');
this.removeAttribute('aria-describedby');
errorContainer.textContent = '';
errorContainer.style.display = 'none';
}
});
Обратите внимание, что поддерживается в новых экранных считывателях, но остается более широко совместимой. Документация MDN обеспечивает тщательное сравнение.
Управление фокусом для инклюзивного потока
В многошаговых формах или при появлении ошибок управление фокусом имеет решающее значение. JavaScript может программно перемещать фокус в первое недействительное поле или в сводку ошибок. Всегда сообщайте причину перемещения фокуса с помощью области или заголовка.
function focusFirstError() {
const firstError = document.querySelector('[aria-invalid="true"]');
if (firstError) {
firstError.focus();
// Optionally announce
const announcer = document.getElementById('form-feedback');
announcer.textContent = 'The form contains errors. The first invalid field has been focused.';
announcer.setAttribute('aria-live', 'assertive');
}
}
document.getElementById('submit-btn').addEventListener('click', function (e) {
if (!validateForm()) {
e.preventDefault();
focusFirstError();
}
});
Будьте осторожны с ; используйте для некритических обновлений. Управление фокусом без объявления может сбить с толку пользователей, поскольку они могут не понимать, почему они были перемещены.
Обработка пользовательских форм контроля
Многие проекты используют флажки, радиокнопки, меню или переключатели переключения. Они теряют нативную семантику и требуют ролей ARIA, состояний и свойств, реализованных через JavaScript. Например, пользовательский флажок нуждается в , и слушателях событий на клавиатуре.
const customCheckbox = document.getElementById('custom-checkbox');
customCheckbox.setAttribute('role', 'checkbox');
customCheckbox.setAttribute('aria-checked', 'false');
customCheckbox.setAttribute('tabindex', '0');
customCheckbox.setAttribute('aria-label', 'Accept terms and conditions');
customCheckbox.addEventListener('click', function () {
const isChecked = this.getAttribute('aria-checked') === 'true' ? false : true;
this.setAttribute('aria-checked', isChecked);
this.classList.toggle('checked', isChecked);
});
customCheckbox.addEventListener('keydown', function (e) {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
this.click();
}
});
Хотя такие шаблоны возможны, предпочтите нативные элементы HTML, когда это возможно: они поставляются со встроенной доступностью, обработкой клавиатуры и минимальными накладными расходами JavaScript.
Лучшие практики использования JavaScript с ARIA
- Начните с семантического HTML. Всегда начинайте с надлежащих ассоциаций и нативных входов перед наложением ARIA. ARIA должна исправить то, что HTML не может.
- Сохраняйте атрибуты ARIA в актуальном состоянии. Убедитесь, что ваш JavaScript обновляет , и доступные имена в режиме реального времени, поскольку взаимодействия пользователей изменяют состояние формы.
- Не переопределяйте родное поведение. Например, не дублируйте с на одном элементе, если вам не нужно поддерживать старые пользовательские агенты; вместо этого позвольте родному атрибуту выполнять работу и добавляйте ARIA только там, где это необходимо.
- Испытания с реальными вспомогательными технологиями. Автоматизированные валидаторы улавливают только около 30% проблем с доступностью. Всегда тестируйте с помощью считывателей экрана (NVDA, VoiceOver, JAWS) и навигации только на клавиатуре.
- По возможности, следует использовать видимые метки. Пользователи с когнитивными нарушениями получают выгоду от видимых меток. Скрытые метки (с использованием или ) следует использовать только тогда, когда дизайн действительно не может вместить видимый текст.
- Использовать живые регионы разумно. Использование может перегрузить пользователей считывающего устройства. для рутинных обновлений и только для чувствительных ко времени объявлений (например, для успеха/неудачи подачи формы).
Полный рабочий пример: доступная динамическая форма регистрации
Ниже приведен краткий пример, который связывает несколько шаблонов: условные поля, динамические метки ARIA, обработка ошибок проверки и управление фокусом. Этот код готов к производству, но упрощен для ясности.
<form id="registration-form" novalidate>
<label for="username">Username (required)</label>
<input type="text" id="username" required>
<label for="newsletter">Subscribe to newsletter</label>
<input type="checkbox" id="newsletter">
<div id="email-group" hidden>
<label for="email">Email</label>
<input type="email" id="email">
</div>
<button type="submit">Register</button>
<div id="form-errors" aria-live="polite"></div>
</form>
<script>
const newsletter = document.getElementById('newsletter');
const emailGroup = document.getElementById('email-group');
const emailInput = document.getElementById('email');
const form = document.getElementById('registration-form');
const errorDisplay = document.getElementById('form-errors');
// Show email field only if newsletter is checked
newsletter.addEventListener('change', function () {
if (this.checked) {
emailGroup.hidden = false;
emailInput.setAttribute('aria-label', 'Email address for newsletter');
emailInput.setAttribute('aria-required', 'true');
emailInput.required = true;
} else {
emailGroup.hidden = true;
emailInput.removeAttribute('aria-label');
emailInput.removeAttribute('aria-required');
emailInput.required = false;
emailInput.value = '';
}
});
// Client-side validation and error display
form.addEventListener('submit', function (event) {
event.preventDefault();
let errors = [];
const username = document.getElementById('username');
if (!username.value.trim()) {
username.setAttribute('aria-invalid', 'true');
username.setAttribute('aria-describedby', 'form-errors');
errors.push('Username is required.');
} else {
username.setAttribute('aria-invalid', 'false');
username.removeAttribute('aria-describedby');
}
if (!emailGroup.hidden && !emailInput.value.trim()) {
emailInput.setAttribute('aria-invalid', 'true');
emailInput.setAttribute('aria-describedby', 'form-errors');
errors.push('Email is required for newsletter subscription.');
} else if (!emailGroup.hidden) {
emailInput.setAttribute('aria-invalid', 'false');
emailInput.removeAttribute('aria-describedby');
}
errorDisplay.textContent = errors.join(' ');
if (errors.length > 0) {
// Focus first error field
const firstErrorField = document.querySelector('[aria-invalid="true"]');
if (firstErrorField) firstErrorField.focus();
} else {
// Successful submission (would send data)
errorDisplay.textContent = 'Registration successful!';
errorDisplay.setAttribute('aria-live', 'assertive');
}
});
</script>
Этот пример демонстрирует, как JavaScript может динамически добавлять , когда появляется поле электронной почты, устанавливать условно, управлять и во время проверки и использовать область для суммирования ошибок.
Заключение
Доступные формы не являются роскошью - они являются фундаментальным требованием для справедливого цифрового доступа. Объединив атрибуты ARIA с JavaScript, разработчики могут создавать интерфейсы, которые реагируют на действия пользователей, сохраняя четкую, последовательную связь с вспомогательными технологиями. Модели, описанные в этой статье - динамическая маркировка, объявления в реальном регионе, связывание ошибок, управление фокусом и обработка пользовательского контроля - предоставляют практический инструментарий для любого веб-разработчика, работающего с интерактивными формами.
Всегда помните, что ARIA является дополнением, а не заменой. Начните с чистого семантического HTML, проверьте с помощью реальных вспомогательных технологий и итерируйте на основе обратной связи с пользователем. При использовании вдумчиво JavaScript и ARIA вместе могут превратить форму из источника разочарования в бесшовный, инклюзивный опыт. Для дальнейшего чтения обратитесь к WAI-ARIA Authoring Practices и WebAIM руководство по доступным формам .