Как сделать аккордеон
Короткий ответ
Тег details раскрывается по клику на summary — без единой строки JavaScript:
<details>
<summary>How long is delivery?</summary>
<p>Usually two to four working days.</p>
</details>
<details>
<summary>Can I return an item?</summary>
<p>Yes, within 30 days of purchase.</p>
</details>Только один открыт
Одинаковый атрибут name у нескольких details превращает их в группу: при открытии одного остальные закрываются:
<style>
.faq { border-bottom: 1px solid gainsboro; padding: 8px 0; }
.faq summary { cursor: pointer; font-weight: 600; list-style: none; display: flex; justify-content: space-between; }
.faq summary::after { content: "+"; }
.faq[open] summary::after { content: "−"; }
</style>
<details class="faq" name="faq" open><summary>Shipping</summary><p>Free from $50.</p></details>
<details class="faq" name="faq"><summary>Payment</summary><p>Cards and PayPal.</p></details>
<details class="faq" name="faq"><summary>Returns</summary><p>Within 30 days.</p></details>list-style: none убирает стандартный треугольник, а ::after рисует свой значок, который меняется у открытого блока [open].
Плавное раскрытие
Раньше details открывался только скачком. В новых браузерах плавность даёт interpolate-size: allow-keywords вместе с transition для псевдоэлемента ::details-content; в остальных блок просто откроется сразу.
Частая ошибка
Делают аккордеон из div с обработчиком клика. Такой блок не открывается с клавиатуры, а экранный диктор не знает, что он раскрывается. details и summary дают всё это бесплатно — используйте их.
Функции из этого ответа
- <details>, <summary> — Раскрывающийся блок без JavaScript: `<summary>` — видимый заголовок, остальное скрыто до клика.
- transition — Плавно анимирует изменение свойства от старого значения к новому.
- ::marker — Маркер или номер пункта списка.