Кратко
СкопированоСвойство виджета из 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.