Аккордеон
Аккордеон — это стопка разделов. У каждого раздела есть заголовок, который показывает или скрывает его содержимое.
Standard shipping arrives in 3 to 5 business days.
Return any unworn item within 30 days for a full refund.
<tk-accordion>
<tk-accordion-item open>
<span slot="header">Shipping</span>
<p>Standard shipping arrives in 3 to 5 business days.</p>
</tk-accordion-item>
<tk-accordion-item>
<span slot="header">Returns</span>
<p>Return any unworn item within 30 days for a full refund.</p>
</tk-accordion-item>
</tk-accordion>Анатомия
| Часть | Что это |
|---|---|
tk-accordion |
стопка разделов; своей остановки Tab нет |
tk-accordion-item |
один раздел |
слот header |
название раздела |
| слот по умолчанию | содержимое, видно, когда раздел открыт |
part header |
заголовок вокруг кнопки |
part trigger |
кнопка заголовка со стрелкой справа; одна остановка Tab |
part panel |
область с содержимым |
Открытый раздел ведёт себя как одна карточка: щелчок в любом месте содержимого закрывает его. Ссылки, кнопки, поля и выделенный текст внутри работают как обычно.
Один или несколько открытых
По умолчанию открыто может быть несколько разделов сразу. С single открыт только один:
открытие раздела закрывает остальные. Закрыть открытый раздел можно всегда.
Yes, at any time.
Yes, from Billing.
<tk-accordion single> <tk-accordion-item open><span slot="header">Can I change my plan?</span><p>Yes, at any time.</p></tk-accordion-item> <tk-accordion-item><span slot="header">Can I cancel?</span><p>Yes, from Billing.</p></tk-accordion-item> </tk-accordion>
Не используйте single, если разделы нужно сравнивать.
Состояния
Name, photo, and bio.
Roles and invites.
<tk-accordion> <tk-accordion-item open><span slot="header">Profile</span><p>Name, photo, and bio.</p></tk-accordion-item> <tk-accordion-item disabled><span slot="header">Team settings</span><p>Roles and invites.</p></tk-accordion-item> </tk-accordion>
При наведении и нажатии подсвечивается строка заголовка, а у открытого раздела вся карточка. При фокусе с клавиатуры внутри строки заголовка появляется рамка.
open: раздел открыт с самого начала. Дальше аккордеон переключает его сам; свойствоopenможно читать и задавать из кода.disabled: раздел нельзя открыть или закрыть, а заголовок выпадает из порядка Tab. Напишите в заголовке, почему раздел недоступен.
Управление вручную
Чтобы сначала загрузить содержимое или проверить условие, слушайте tk-toggle и вызовите
preventDefault(), а когда всё готово, задайте open. В event.detail.open — состояние,
в которое переходит раздел.
<tk-accordion-item id="reports"><span slot="header">Reports</span><div id="reports-body"></div></tk-accordion-item>
<script>
const item = document.getElementById('reports');
item.addEventListener('tk-toggle', async (e) => {
if (!e.detail.open) return;
e.preventDefault();
await loadReports();
item.open = true;
});
</script>Уровень заголовка
Каждый заголовок раздела — настоящий заголовок, по умолчанию третьего уровня. Задайте
heading-level у tk-accordion, чтобы заголовки вписались в структуру страницы: под
<h2> нужен 3. У отдельного раздела heading-level переопределяет уровень только для него.
Used on invoices.
<tk-accordion heading-level="4"> <tk-accordion-item><span slot="header">Billing address</span><p>Used on invoices.</p></tk-accordion-item> </tk-accordion>
Когда использовать
- Аккордеон — для длинного содержимого, разбитого на разделы, которые можно пропустить: вопросы и ответы, группы настроек, описание товара.
- Не прячьте то, что обязательно нужно увидеть: важные инструкции, ошибку, обязательное поле.
- Чтобы переключаться между видами одной области, берите
Tab bar . - Для вложенных данных берите
Tree . У аккордеона один уровень. - Для одиночного «показать или скрыть» без заголовка берите
Collapsible . Аккордеон из одного раздела уместен, когда разделу нужен заголовок.
Текст
- Заголовок раздела короткий и не повторяется. Он же называет раздел для скринридера, поэтому не пишите везде «Подробнее».
- Заглавная буква только в начале, без точки в конце. В разделе вопросов заголовки могут быть вопросами.
Можно / нельзя
| ✅ Можно | ❌ Нельзя |
|---|---|
| Длинное содержимое, которое можно пропустить | Прятать в нём инструкции, ошибки или обязательные поля |
heading-level под структуру страницы |
Оставлять заголовки неправильного уровня |
single для вопросов, где важен один ответ |
single, когда разделы сравнивают |
| Свой заголовок у каждого раздела | «Подробнее» в каждом заголовке |
| Tab bar для видов одной области | Делать вкладки из аккордеона с single |
Связанные
Collapsible : одно «показать или скрыть» без заголовка.Tab bar : переключение между видами одной области.Tree : вложенные данные.Dialog : содержимое, которое должно прервать работу.
API
Атрибуты tk-accordion
| Атрибут | Тип | По умолчанию | Что делает |
|---|---|---|---|
single |
boolean | false |
открыт только один раздел |
heading-level |
number | 3 |
уровень всех заголовков, от 1 до 6 |
Атрибуты tk-accordion-item
| Атрибут | Тип | По умолчанию | Что делает |
|---|---|---|---|
open |
boolean | false |
раздел открыт; свойство живое |
disabled |
boolean | false |
не переключается; заголовок выпадает из порядка Tab |
heading-level |
number | как у контейнера | уровень заголовка только для этого раздела |
Слоты
| Элемент | Слот | Содержимое |
|---|---|---|
tk-accordion |
по умолчанию | разделы tk-accordion-item |
tk-accordion-item |
header |
название раздела |
tk-accordion-item |
по умолчанию | содержимое |
События
tk-accordion-item вызывает tk-toggle, когда пользователь открывает или закрывает
раздел, до смены состояния. detail.open — новое состояние. Событие всплывает, поэтому
его можно слушать на tk-accordion. preventDefault() отменяет смену, и open вы
задаёте сами.
Методы
tk-accordion-item.focus() переводит фокус на заголовок раздела.
CSS
tk-accordion-item::part(header): заголовок вокруг кнопки.tk-accordion-item::part(trigger): кнопка заголовка,<button>.tk-accordion-item::part(panel): область с содержимым.
Токены
| Элемент | Токен |
|---|---|
| текст заголовка | text/default; отключённый text/disabled |
| стрелка | icon/secondary, icon-size-16 |
| наведение, нажатие | state/hover, state/press, с radius-8 |
| рамка фокуса | border/accent/focus, внутри строки |
| текст содержимого | text/default |
Заголовок набран стилем Label Large (16/24, medium), его высота не меньше 48px, отступы
space-12 сверху и снизу, space-16 по бокам и space-8 перед стрелкой. У содержимого
отступы space-16 по бокам и снизу. Линий между разделами нет; если нужна граница,
задайте её контейнеру вокруг. Значения по темам:
Доступность
Встроено:
- Каждый заголовок — кнопка внутри заголовка, поэтому скринридер читает «Shipping, заголовок уровня 3, кнопка, свёрнуто», а навигация по заголовкам доходит до каждого раздела.
- Кнопка сообщает, раскрыт ли раздел.
- Содержимое открытого раздела — область, названная его заголовком.
- Содержимое закрытого раздела скрыто от скринридеров, и на него нельзя перейти фокусом.
- Стрелка скрыта от скринридеров.
- При настройке «уменьшить движение» разделы открываются и закрываются без анимации.
На вашей стороне:
- Задайте
heading-levelпод структуру страницы. - Не делайте разделов слишком много: каждый открытый раздел — ориентир-область, и десятки таких областей засоряют список ориентиров в скринридере.
- На тёмном или цветном фоне контраст текста заголовка должен быть не ниже 4.5:1.
| Клавиша | Действие |
|---|---|
Tab |
переводит на следующий заголовок, затем в содержимое открытого раздела |
Enter / Space |
открывает или закрывает раздел в фокусе |
Down / Up |
переводит на следующий или предыдущий доступный заголовок; по кругу не ходит |
Home / End |
переводит на первый или последний доступный заголовок |