Кратко
СкопированоСвойство виджета из WAI-ARIA. Указывает на то, что элемент формы нужно обязательно заполнить или выбрать.
aria
не влияет на функциональность и поведение элемента, а лишь помогает вспомогательным технологиям сообщать пользователям об обязательности поля.
Аналог aria
в HTML — атрибут required
.
Пример
Скопировано<span id="input-label">Ваша почта:</span><span role="textbox" aria-labelledby="input-label" id="email" aria-required="true" contenteditable></span>
<span id="input-label">Ваша почта:</span> <span role="textbox" aria-labelledby="input-label" id="email" aria-required="true" contenteditable > </span>
Другой пример:
<label for="name">Ваше имя (обязательно):</label><input id="name" type="text" name="name" aria-invalid="false" aria-required="true" aria-describedby="error"><div class="error-message" id="error"> Заполните это поле 🤗</div>
<label for="name">Ваше имя (обязательно):</label> <input id="name" type="text" name="name" aria-invalid="false" aria-required="true" aria-describedby="error" > <div class="error-message" id="error"> Заполните это поле 🤗 </div>
Как пишется
СкопированоДобавьте атрибут aria
к интерактивным элементам, которые принимают данные пользователей:
<input type
или= "checkbox"> checkbox
;<select>
илиcombobox
иlistbox
;<textarea>
,<input>
с типамиtext
,email
,tel
,url
или ролиtextbox
;<input type
или= "number"> spinbutton
;div
,span
илиgeneric
;radiogroup
;tree
;gridcell
.
У aria
есть два значения:
true
— нужно обязательно ввести сюда данные или сделать выбор;false
(по умолчанию) — данные вводить необязательно.
Для <input>
, <select>
или <textarea>
лучше использовать атрибут required
. ARIA-атрибут обычно используют с кастомными элементами форм, которые свёрстаны при помощи <div>
или <span>
.
Другой случай для aria
— улучшение нативного поведения required
и браузерной валидации. Например, браузерная подсказка может быстро пропадать после появления, оставаться маленькой при увеличении интерфейса, не подхватывать язык браузера и ломаться при плавной прокрутке к полю.
aria
можно добавлять не только к отдельным полям и радиокнопкам, но и к целым группам элементов:
<form> <fieldset aria-required="true" > <legend> Выберите хотя бы одно увлечение: </legend> <label> <input type="checkbox" name="hobbies" value="reading"> Книги </label> <label> <input type="checkbox" name="hobbies" value="cats"> Котики </label> <label> <input type="checkbox" name="hobbies" value="traveling"> Путешествия </label> </fieldset> <button>Отправить</button></form>
<form> <fieldset aria-required="true" > <legend> Выберите хотя бы одно увлечение: </legend> <label> <input type="checkbox" name="hobbies" value="reading"> Книги </label> <label> <input type="checkbox" name="hobbies" value="cats"> Котики </label> <label> <input type="checkbox" name="hobbies" value="traveling"> Путешествия </label> </fieldset> <button>Отправить</button> </form>
При использовании aria
, настройте валидацию через JavaScript.
<form id="form" method="post" novalidate> <label for="name">Ваше имя (обязательно):</label> <input id="name" type="text" name="name" aria-invalid="false" aria-required="true" aria-describedby="error" > <div class="error-message" id="error" > Заполните это поле 🤗 </div> <button id="button">Отправить</button></form>
<form id="form" method="post" novalidate > <label for="name">Ваше имя (обязательно):</label> <input id="name" type="text" name="name" aria-invalid="false" aria-required="true" aria-describedby="error" > <div class="error-message" id="error" > Заполните это поле 🤗 </div> <button id="button">Отправить</button> </form>
const form = document.getElementById('form')const requiredInput = form.querySelector('#name')const button = form.querySelector('#button')const error = form.querySelector('#error')const markValid = () => { requiredInput.setAttribute('aria-invalid', 'false') error.style.display = 'none'}const markInvalid = () => { requiredInput.setAttribute('aria-invalid', 'true') error.style.display = 'block'}const validateInput = () => { const value = requiredInput.value if (!value) { markInvalid() } else { markValid() }}const hideError = () => { const value = requiredInput.value if (value) { markValid() }}button.addEventListener('click', () => { validateInput()})requiredInput.addEventListener('change', validateInput)requiredInput.addEventListener('input', hideError)form.addEventListener('submit', (event) => { event.preventDefault() button.disabled = true // Исправляем поведение Firefox button.autocomplete = 'off' setTimeout(() => { button.disabled = false }, 2000)})
const form = document.getElementById('form') const requiredInput = form.querySelector('#name') const button = form.querySelector('#button') const error = form.querySelector('#error') const markValid = () => { requiredInput.setAttribute('aria-invalid', 'false') error.style.display = 'none' } const markInvalid = () => { requiredInput.setAttribute('aria-invalid', 'true') error.style.display = 'block' } const validateInput = () => { const value = requiredInput.value if (!value) { markInvalid() } else { markValid() } } const hideError = () => { const value = requiredInput.value if (value) { markValid() } } button.addEventListener('click', () => { validateInput() }) requiredInput.addEventListener('change', validateInput) requiredInput.addEventListener('input', hideError) form.addEventListener('submit', (event) => { event.preventDefault() button.disabled = true // Исправляем поведение Firefox button.autocomplete = 'off' setTimeout(() => { button.disabled = false }, 2000) })
Чтобы пользователь понял, что поле обязательное, используйте текст или знак звёздочки *
(астериск) вместе с цветом. Это важно для пользователей с особенностями зрения. Например, обязательные поля с aria
можно выделить с помощью CSS-селекторов:
[aria-required="true"] { border: 2px solid red;}
[aria-required="true"] { border: 2px solid red; }
Или показать подсказки:
[aria-required="true"]::after { content: "*"; color: red;}
[aria-required="true"]::after { content: "*"; color: red; }
Если все поля нужно заполнить, лучше укажите это в начале формы, а не добавляйте атрибут к каждому полю.
<form aria-describedby="hint"> <p id="hint">Обязательно заполните все поля 💯</p> <label for="name">Имя:</label> <input type="text" id="name" value="name" aria-required="true"> <label for="lastname">Фамилия:</label> <input type="text" id="lastname" value="lastname" aria-required="true"> <button>Отправить</button></form>
<form aria-describedby="hint"> <p id="hint">Обязательно заполните все поля 💯</p> <label for="name">Имя:</label> <input type="text" id="name" value="name" aria-required="true"> <label for="lastname">Фамилия:</label> <input type="text" id="lastname" value="lastname" aria-required="true"> <button>Отправить</button> </form>
Скрывайте от скринридеров избыточные подсказки через атрибут aria
:
<form> <label for="name">Имя*:</label> <input type="text" id="name" value="name" aria-required="true"> <label for="lastname">Фамилия*:</label> <input type="text" id="lastname" value="lastname" aria-required="true"> <label for="biography">Расскажите о себе:</label> <textarea id="biography" type="text"></textarea> <p aria-hidden="true"> * — обязательное поле </p> <button>Отправить</button></form>
<form> <label for="name">Имя*:</label> <input type="text" id="name" value="name" aria-required="true"> <label for="lastname">Фамилия*:</label> <input type="text" id="lastname" value="lastname" aria-required="true"> <label for="biography">Расскажите о себе:</label> <textarea id="biography" type="text"></textarea> <p aria-hidden="true"> * — обязательное поле </p> <button>Отправить</button> </form>
Подсказки
Скопировано💡 Атрибуты required
и aria
одинаково интерпретируются скринридерами.
💡 Чтобы форма не отправлялась с пустыми полями, настройте проверку через JavaScript.
💡 Для поддержки старых браузеров можно использовать required
и aria
одновременно. Современные браузеры проигнорируют aria
и отдадут приоритет нативному required
.