Марианна Минич пишет:
На какие угодно ухищрения готовы пойти разработчики, лишь бы не использовать семантичную <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