Просто используй кнопку
- понедельник, 3 ноября 2025 г. в 00:00:06

Мне часто доводится вести странные споры с фанатами фреймворков о том, действительно ли <div> «столь же хорош», как и <button>.
Спойлер: нет. И давайте выясним, почему.
В среде разработчиков на React, а также у тех, кому нравится HTMX, я часто вижу такое…
<div onclick="showSignIn()">
Open Modal
</div>function showSignIn () {
// Код для отображения модального окна входа.
// Подробности реализации зависят от стека.
}Что здесь не так?
Этот элемент не сообщает о себе как об интерактивном элементе пользователям программ для чтения экрана.
Нельзя получить фокус <div> с клавиатуры.
Событие срабатывает только по click, но не при нажатии на клавиши Enter или пробел (клавиатурные пользователи снова страдают).
Я встречал такое во многих кодовых базах. И во многих демо.
Я спорил с очень известным идейным лидером React, имя которого начинается на Р: он настаивал, что <div> обеспечивает «бóльшую accessibility», чем <button>, и что команда Twitter приняла правильное решение, когда стала использовать этот паттерн в своём приложении.
Всё это совсем-совсем неправильно.
Многие HTML-элементы имеют собственные роли, сообщающие вспомогательным приложениям, например, программам для чтения экрана, что они делают.
Элемент <button> — один из них. У него есть внутренняя [роль] кнопки, и это даёт пользователям программ чтения экрана понять, что с ним можно взаимодействовать и вызывать некое поведение в приложении.
HTML-атрибут [role] можно использовать для добавления и изменения роли элемента. Поэтому люди вроде Рай... лидера мнений React говорят что-то подобное (передаю общий смысл)…
Этот атрибут существует не просто так, можно добавить
[role="button"]кdiv, чтобы придать ему корректную семантику.
Допустим, но это решает только одну проблему.
Эта роль не влияет на возможность фокусировки (или её отсутствие) и клавиатурное поведение. Пользователи с нарушением зрения, выполняющие навигацию с клавиатуры, всё равно не могут ею воспользоваться.
Вам скажут: «Не волнуйтесь! Это тоже можно исправить!»
Можно добавить элементу возможность фокусировки при помощи атрибута [tabindex].
<div
onclick="showSignIn()"
tabindex="0"
>
Open Modal
</div>Однако делать этого не стоит! Серьёзно, не надо вмешиваться в порядок фокусировки.
Слишком легко пойти по этому пути, а затем всё поломать, из-за чего пользователи будут скакать по всей странице вместо того, чтобы двигаться по ней в обычном и предсказуемом порядке.
И опять-таки, интерактивность с клавиатуры всё ещё отсутствует.
Но не беспокойтесь! Можно и её добавить. Достаточно просто слушать все события keydown, а затем фильтровать их по event.key , чтобы код выполнялся только при нажатии на Enter или пробел (последнее означает проверку на буквальный пробел: ' ').
Но этот код нельзя выполнять и на элементе. Нужно прикрепить это событие к document и разбираться, у какого элемента есть фокус.
document.addEventListener('keydown', (event) => {
// Выполняем только при нажатии на Enter и пробел
if (event.key !== 'Enter' & event.key !== ' ') return;
// Проверяем, что фокус на элементе, который нам нужен
const notRealBtn = document.activeElement.closest('[onclick]');
if (!notRealBtn) return;
// Каким-то образом выполняем наш код...
});Хм... допустим, строго говоря, так мы устранили проблему, но...
Серьёзно: на кой чёрт нам всё это делать?!?
Вся эта возня ради того, чтобы написать такой HTML…
<div
onclick="showSignIn()"
tabindex="0"
>
Open Modal
</div>Когда можно просто написать так:
<button onclick="showSignIn()">
Open Modal
</button>У <button>…
Изначально имеется нужная [role].
Есть автоматическая возможность фокусировки.
Запускается событие click в ответ на нажатия Enter и Spacebar, если кнопка находится в фокусе.
Послушайте, я ленивый разработчик.
И, подозреваю, если вы любите инструменты наподобие React, то, вероятно, вы тоже ленивы. И это здорово! Лучший код — это код ненаписанный, и всё такое прочее.
Так что будьте ещё ленивее.
Используйте для этой задачи идеально подходящий элемент, ведь тогда вам не придётся писать кучу лишнего кода!