Неактивные кнопки и доступность
Обновлено 14 октября 2026 г. · 6 мин чтения
Серая кнопка «В корзину», пока не выбран размер, кнопка «Оформить заказ», которая остаётся неактивной, пока не заполнены все поля, — неактивные кнопки встречаются в интернет-магазинах повсюду. У WCAG для них есть отдельное исключение, но это не делает их хорошей идеей в любом случае. На этой странице разобраны правила, два способа отключить кнопку и лучшие альтернативы. Она входит в серию доступных UI-паттернов.
Что говорит WCAG
- Исключение для контраста. 1.4.3 Контраст (минимальный) освобождает «текст или изображения текста, являющиеся частью неактивного компонента пользовательского интерфейса», а 1.4.11 Контраст нетекстового контента освобождает неактивные компоненты тоже. W3C определяет неактивный компонент как «видимый, но в данный момент неработающий» и приводит в пример отключённую кнопку отправки. В документе Understanding объясняется, что исключение существует потому, что единого хорошего способа показать отключённые элементы не найдено.
- Имя, роль, состояние. 4.1.2 Имя, роль, значение: отключённое состояние должно быть доступно в коде, а не только серым цветом.
- Инструкции. 3.3.2 Подписи или инструкции: если перед тем, как кнопка заработает, пользователь должен что-то сделать, скажите об этом.
- Ошибки. 3.3.1 Обнаружение ошибок: отключённая кнопка отправки — не сообщение об ошибке. Пользователю всё равно нужно узнать текстом, что не так.
Так что низкий контраст у неактивной кнопки не нарушает WCAG, но неактивная кнопка, которую никто не может понять, всё же может нарушать перечисленные выше критерии и наверняка стоит вам продаж.
disabled и aria-disabled
Атрибут disabled |
aria-disabled="true" |
|
|---|---|---|
| Работает на | Нативных элементах форм: button, input, select, textarea, fieldset |
Любом элементе с интерактивной ролью |
| Можно активировать | Нет, браузер блокирует | Да — ваш скрипт должен игнорировать действие |
| В последовательности перехода по Tab | Нет | Да |
| Экранный диктор объявляет «недоступно» / «затемнено» | Да | Да |
В руководстве APG по клавиатуре сказано: «браузеры убирают HTML-элементы ввода с атрибутом disabled из последовательности перехода по Tab». Там, где пользователям нужно обнаружить отключённый элемент — APG упоминает пункты меню, вкладки, варианты списка и элементы дерева, — используется aria-disabled="true", чтобы элемент оставался доступным для фокуса. В шаблоне кнопки APG также сказано, что когда действие кнопки недоступно, «у кнопки aria-disabled равен true».
Практическое правило: используйте disabled, когда не важно, что кнопку пропускают; используйте aria-disabled, когда пользователям нужно найти кнопку и узнать, почему она не работает.
Пример кода
<!-- Discoverable: stays in the tab order, the reason is announced -->
<p id="size-hint">Выберите размер, чтобы добавить этот товар в корзину.</p>
<button type="button" id="add" aria-disabled="true" aria-describedby="size-hint">
В корзину
</button>
<script>
const add = document.getElementById('add');
add.addEventListener('click', (event) => {
if (add.getAttribute('aria-disabled') === 'true') {
event.preventDefault(); // block the action yourself
document.getElementById('size').focus();
return;
}
addToCart();
});
// When a size is selected: add.setAttribute('aria-disabled', 'false');
</script>
<!-- Fine to skip: a native disabled control the user does not need to reach -->
<button type="button" disabled>Предыдущая страница</button>
Оформите [aria-disabled="true"] так, чтобы кнопка выглядела недоступной, — браузер этого за вас не сделает.
Лучшие альтернативы
- Оставьте «Оформить заказ» активной. Если её нажали при недостающих данных, покажите сообщения об ошибках текстом и переместите фокус на первую ошибку или сводку ошибок. См. проверку форм и ошибки.
- Скажите, что нужно, рядом с неактивной кнопкой, видимым текстом, а не во всплывающей подсказке при наведении.
- Не скрывайте недоступный вариант без объяснения — распроданный размер может остаться в списке с пометкой «нет в наличии».
Работа с клавиатуры
| Клавиша | Кнопка с disabled |
Кнопка с aria-disabled |
|---|---|---|
| Tab | Пропускает кнопку | Перемещает на неё фокус; экранный диктор говорит, что она недоступна, и зачитывает описание |
| Enter / пробел | Ничего | Ничего не происходит — или скрипт переносит фокус на то, чего не хватает |
Частые ошибки в интернет-магазинах
- «В корзину» неактивна, пока не выбран вариант, и нет видимой подсказки. Пользователи клавиатуры никогда не доходят до кнопки и не знают почему.
- Кнопка «Оплатить» при оформлении заказа неактивна, пока все поля не пройдут проверку, а поля не показывают сообщений об ошибках.
- Кнопка, которая выглядит неактивной, но не является ею (только серый стиль), или отключена в коде, но выглядит активной.
aria-disabled="true"без защиты в скрипте, так что кнопка всё равно отправляет форму.- Отключённое состояние показано только пониженной непрозрачностью, а причина появляется во всплывающей подсказке
title. - Нечитаемо светлый неактивный текст для важной информации, например «Нет в наличии». Текст может быть освобождён от требований к контрасту, но информация должна быть доступна и читаемым текстом.
Что находит автоматика и что остаётся для ручной проверки
| Автоматическая (правило axe-core) | Что находит |
|---|---|
color-contrast |
Текст с низким контрастом; отключённые элементы пропускаются, как их освобождает WCAG |
button-name |
Кнопки без имени, отключённые или нет |
aria-valid-attr-value |
aria-disabled с недопустимым значением, aria-describedby, указывающий на несуществующий ID |
aria-allowed-attr |
Атрибуты ARIA, не допустимые для роли элемента |
Все они — карточки в нашей библиотеке правил. Ручная проверка: попробуйте заполнить форму или выбрать товар только с клавиатуры, убедитесь, что у каждого отключённого элемента есть видимая причина, и проверьте с экранным диктором, что состояние и причина объявляются. Инструмент проверки контраста поможет выбрать стиль для неактивных элементов, который остаётся читаемым.
Запустите бесплатную проверку одной страницы. Это автоматическая проверка, а не полный аудит.
Частые вопросы
Должны ли неактивные кнопки соответствовать требованиям WCAG к контрасту?
Нет. И 1.4.3 «Контраст (минимальный)», и 1.4.11 «Контраст нетекстового контента» освобождают неактивные компоненты интерфейса, которые W3C определяет как видимые, но в данный момент неработающие. Пример от W3C — отключённая кнопка отправки.
В чём разница между disabled и aria-disabled?
HTML-атрибут disabled делает нативный элемент неработающим и убирает его из последовательности перехода по Tab. aria-disabled="true" лишь сообщает ассистивным технологиям, что элемент недоступен; он остаётся доступным для фокуса, а действие вы должны заблокировать в своём скрипте.
Плохо ли отключать кнопку отправки, пока форма не станет корректной?
Это часто создаёт проблемы: пользователи не могут узнать, чего не хватает, а пользователи клавиатуры вообще не могут добраться до кнопки. Обычно лучше оставить её активной и показывать понятные сообщения об ошибках при отправке.
Как объяснить, почему кнопка неактивна?
Напишите причину видимым текстом рядом с кнопкой, например «Выберите размер, чтобы добавить в корзину», и свяжите его через aria-describedby. Не полагайтесь на подсказку при наведении.
Может ли автоматическая проверка проверить неактивные кнопки?
Проверки контраста пропускают неактивные элементы, как и WCAG. Автоматические правила проверяют, что у aria-disabled допустимое значение и у кнопок есть имя. Понимают ли пользователи, почему кнопка недоступна, проверяется вручную.
Источники
- W3C, Understanding 1.4.3 Contrast (Minimum): https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html
- W3C, Understanding 1.4.11 Non-text Contrast: https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html
- W3C WAI, APG Developing a Keyboard Interface (focusability of disabled controls): https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/
- W3C WAI, APG Button pattern: https://www.w3.org/WAI/ARIA/apg/patterns/button/