TGViewer
<divelopers> <divelopers> @alexnozer_dev · 1.18K subscribers
Post #287 1.04K
Псевдо-кнопки

Марианна Минич пишет:

На какие угодно ухищрения готовы пойти разработчики, лишь бы не использовать семантичную <button> 😅


И сопровождается пост подобным примером:

<div
tabindex="0"
role="button"
class="button"
(mouseenter)="onMouseEnter"
(mouseleave)="onMouseLeave"
(click)="onClick"
(keydown)="onKeyDown"
[attr.aria-pressed]="isPressed"
[attr.aria-label]="label"
...
>
...
</div>


Подобное периодически встречается в кодовых базах, когда разработчики задумываются о доступности или приходят соответствующие специалисты и просят исправить кнопки. Раз просят, нужно исправлять:

- tabindex="0", чтобы не фокусируемый <div> попал в последовательность табуляции и стал доступен для клавиатуры;
- role="button", чтобы семантически нейтральный <div> попал в дерево доступности как кнопка и корректно обрабатывался вспомогательными технологиями;
- keydown, чтобы нажатия клавиш Enter и Space приводили к нажатию на <div> и вызову события click;
- aria-pressed, чтобы передавать в дерево доступности информацию о том, находится ли кнопка в нажатом состоянии;
- aria-label, чтобы задать кнопке имя для дерева доступности, которое переопределяет текстовый контент внутри (если его нет, как в случае с кнопками-иконками).

Эти манипуляции нужны, чтобы «исправить» кнопки и воспроизвести поведение <button> у <div>. Но это не всё: отправка, сброс и переопределение параметров формы, отключение, управление поповером и вызов команд — это то, что сегодня умеет <button>.

Поэтому просто используйте <button>! Причина создания псевдо-кнопок из <div> в стилизации. У <button> специфические стили, которые отличаются от браузера к браузеру. У <div> таких стилей нет и всё одинаково во всех браузерах.

Вместо написания лишнего JS для воспроизведения поведения у <div>, куда проще сделать сброс стилей у <button>, применив all: unset. Важно вернуть стандартную рамку фокуса (или реализовать свою), так как all: unset сбрасывает её:

button {
all: unset;
}

button:focus-visible {
outline: auto;
}


Два CSS-свойства вместо десятков строк кода на JS и полотна из атрибутов в HTML (или директив в шаблоне компонента фреймворка), чтобы получить стилизуемую, семантическую, доступную кнопку со всеми её встроенными возможностями и API.

#html #css #a11y
  • 👍 28
  • ❤ 11
  • ❤‍🔥 3
  • 👏 3
  • 🤡 1
More from @alexnozer_dev
  1. Sep 23, 2026Images Preview На некоторых сайтах, где надо показывать изображения в высоком качестве, дл…
  2. Sep 21, 2026Реализация пользовательских атрибутов Под конец прошлого года я рассказывал об API пользов…
  3. Sep 14, 2026Подклассы Event вместо CustomEvent Многие библиотеки предоставляют систему событий в качес…
  4. Sep 11, 2026Эволюция стилей в темах Shopify Адам Ватан на днях поделился новостью, что Shopify выкупил…
  5. Sep 9, 2026Persistent Widgets Многие сайты не должны быть SPA. Но иногда эта архитектура продиктована…
  6. Sep 7, 2026Processing Instructions и маркеры В DOM всё представлено в виде узлов (Node) разных типов.…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →