Какие HTML теги использовать для семантической разметки аккордеона и почему
Что проверяют
Знаете ли вы нативные элементы и паттерн доступного аккордеона, или соберёте его из div с обработчиками. Следом обычно спрашивают, как сделать, чтобы открыта была только одна секция, и что услышит пользователь экранного диктора.
Как отвечать
Первый вариант, который стоит назвать, это <details> и <summary>. Браузер сам даёт состояние через атрибут open, фокус, реакцию на Enter и пробел, понятную дикторам роль и работу без JavaScript. Атрибут name с одинаковым значением на нескольких <details> делает эксклюзивный аккордеон: открытие одной секции закрывает остальные, поддержка есть во всех актуальных браузерах. Ограничения тоже назовите: анимировать высоту и тонко стилизовать маркер у нативного элемента сложнее, хотя новые возможности вроде ::details-content это постепенно исправляют.
Второй вариант, по паттерну WAI-ARIA для собственного аккордеона:
- заголовок нужного уровня, например
<h3>: даёт навигацию по заголовкам, дикторы умеют по ним прыгать; <button>внутри заголовка: кликабельный элемент с клавиатурой из коробки, на нёмaria-expandedиaria-controlsс id панели;- панель:
<div>с тем самым id, скрытый атрибутомhidden. Рольregionсaria-labelledbyдобавляют, когда секций немного: при большом их числе она засоряет навигацию по ориентирам.
Обёртка <section> вокруг каждой секции необязательна: без доступного имени она для вспомогательных технологий ничем не отличается от div. Смысл аккордеону дают заголовок и кнопка с состоянием.
Где спотыкаются
Вешают клик на сам заголовок или на div. Мышью работает, с клавиатуры и в дикторе нет.
Ставят aria-expanded на панель вместо кнопки. Состояние объявляется на элементе, который его переключает, иначе диктор ничего не скажет при нажатии.
Кладут внутрь <summary> ссылки и другие интерактивные элементы. Диктор воспринимает summary как кнопку, и вложенный интерактив становится недоступным или ведёт себя непредсказуемо.