Кратко
Скопированоaria
— это состояние виджета из WAI-ARIA, которое указывает, в каком состоянии находится кнопка-переключатель (тогл). Этот атрибут помогает вспомогательным технологиям правильно интерпретировать и озвучивать состояние интерактивного элемента.
В HTML нет прямого аналога для aria
, поэтому атрибут необходим для создания доступных переключателей.
Пример
СкопированоПример кнопки-переключателя, которая отображает состояние «Включено»:
<button aria-pressed="true">Пауза</button>
<button aria-pressed="true">Пауза</button>
Состояние кнопки при нажатии должно меняться с помощью JavaScript. По умолчанию устанавливаем значение false
:
<button aria-pressed="false">Пауза</button>
<button aria-pressed="false">Пауза</button>
Как пишется
СкопированоАтрибут aria
принимает одно из следующих значений:
true
— переключатель в состоянии «включён».false
— переключатель в состоянии «выключен».mixed
— переключатель в смешанном (частично активном) состоянии. Это значение используется, когда элемент отражает состояние группы связанных переключателей, часть из которых включена, а часть — выключена.undefined
(по умолчанию) — элемент ничего не переключает.
aria
можно использовать только с <button>
или элементами с ролью button
. Если не добавить aria
, скринридеры не будут воспринимать кнопку как переключатель.
Подводные камни и особенности
СкопированоОбязательное использование JavaScript: для того, чтобы aria
работал правильно, меняйте значение атрибута с помощью JavaScript в момент, когда пользователь нажимает на кнопку.
Визуальная обратная связь: сделайте так, чтобы состояние переключателя было видно всем пользователям.
Отличие от чекбоксов: хотя aria
и <input type
могут выполнять похожие задачи, используйте чекбоксы для форм, а aria
— для действий с немедленным эффектом.
aria
применяется, когда действие выполняется сразу и не требует подтверждения. К примеру, переключение звука или смена темы.
Тип checkbox
применяется в формах, когда собираем данные для последующей отправки. Например, согласие с условиями или выбор опций.
Особенности для скринридеров
СкопированоСкринридеры объявляют состояние кнопки с aria
следующим образом:
aria
— «Кнопка нажата», «Переключатель включён» и похожие формулировки.- pressed = "true" aria
— «Кнопка не нажата», «Переключатель выключен».- pressed = "false" aria
— «Кнопка частично нажата», «Переключатель в смешанном состоянии».- pressed = "mixed"
Интеграция с CSS
СкопированоДля полноценной работы переключателя важно применять разные стили для разных состояний:
[aria-pressed="true"] { background-color: #4CAF50; color: #FFFFFF;}[aria-pressed="false"] { background-color: #F1F1F1; color: #000000;}[aria-pressed="mixed"] { background-color: #FFC107; color: #000000;}
[aria-pressed="true"] { background-color: #4CAF50; color: #FFFFFF; } [aria-pressed="false"] { background-color: #F1F1F1; color: #000000; } [aria-pressed="mixed"] { background-color: #FFC107; color: #000000; }
Интеграция с JavaScript
СкопированоЧтобы при нажатии на переключатель его состояние менялось, можно сделать так:
document.querySelectorAll('button[aria-pressed]').forEach((button) => { button.addEventListener('click', () => { // Переключаем состояние const pressed = button.getAttribute('aria-pressed') === 'true' button.setAttribute('aria-pressed', String(!pressed)) })})
document.querySelectorAll('button[aria-pressed]').forEach((button) => { button.addEventListener('click', () => { // Переключаем состояние const pressed = button.getAttribute('aria-pressed') === 'true' button.setAttribute('aria-pressed', String(!pressed)) }) })
Демонстрация работы
СкопированоВ примере кнопка меняет своё состояние и визуальный стиль при нажатии:
В демо текст кнопки меняется при переключении состояний. В реальных проектах, чаще всего, в переключателе не меняют текст и оставляют постоянный, например, «Субтитры» или «Воспроизведение». Так интерфейс становится понятнее и удобнее для всех пользователей. Для отображения включённого или выключенного состояния используют цвета вместе с иконками или другими визуальными подсказками.
Как понять
СкопированоПереключатели (тоглы) — это специальные кнопки, которые могут находиться в двух или более состояниях. Типичные примеры:
- кнопка «Пауза» или «Воспроизведение» в плеере;
- переключатель светлой или тёмной темы;
- кнопка включения или выключения микрофона;
- кнопка «Нравится» в социальных сетях.
В отличие от обычных кнопок, которые выполняют одноразовое действие при нажатии, кнопки-переключатели меняют состояние и сохраняют его. aria
помогает вспомогательным технологиям правильно объявлять текущее состояние кнопки, что делает интерфейс более понятным и предсказуемым.
Подсказки
Скопировано💡 Обеспечивайте визуальную обратную связь для разных состояний переключателей.
💡 При разработке интерфейса с переключателями полезно продумать последовательную стилизацию похожих элементов.
💡 Рекомендуют писать, что делает кнопка, а не в каком она сейчас состоянии. Например, просто «Звук», а не «Включить звук» или «Выключить звук».
💡 Тестируйте интерфейс со скринридерами, чтобы убедиться, что состояния кнопок-переключателей правильно озвучиваются.
💡 Если переключатель управляет другим элементом, например, раскрывает панель вкладок или меню, рекомендуют использовать атрибут aria
. Атрибут явно связывает кнопку с элементом. Это поможет вспомогательным технологиям понять, чем именно управляет переключатель.
На практике
Скопированосоветует Скопировано
В современных JavaScript-фреймворках aria
легко интегрируется в компонентный подход.
Пример React-компонента:
function ToggleButton({ label, initialState = false }) { const [isPressed, setIsPressed] = React.useState(initialState) return ( <button aria-pressed={isPressed} onClick={() => setIsPressed(!isPressed)} > {label} </button> )}
function ToggleButton({ label, initialState = false }) { const [isPressed, setIsPressed] = React.useState(initialState) return ( <button aria-pressed={isPressed} onClick={() => setIsPressed(!isPressed)} > {label} </button> ) }
Пример Vue-компонента:
<template> <button :aria-pressed="isPressed" @click="togglePressed" > {{ label }} </button></template><script setup>import { ref } from 'vue'const props = defineProps({ label: { type: String, required: true }, initialState: { type: Boolean, default: false }})const isPressed = ref(props.initialState)function togglePressed() { isPressed.value = !isPressed.value}</script>
<template> <button :aria-pressed="isPressed" @click="togglePressed" > {{ label }} </button> </template> <script setup> import { ref } from 'vue' const props = defineProps({ label: { type: String, required: true }, initialState: { type: Boolean, default: false } }) const isPressed = ref(props.initialState) function togglePressed() { isPressed.value = !isPressed.value } </script>