Перейти к содержимому
Плотность
Тема

Обратная связь

Аккордеон

Группа сворачиваемых разделов, из которых открыт ровно один. На нативных <details> с общим name, поэтому взаимное исключение, раскрытие и клавиатура достаются от платформы — без единой строки JS.

Компонент
Почему прогон занял 42 секунды?
Три прохода расстановки ресурсов плюс запекание навмеша. Основное время ушло на валидацию путей, которая перезапускалась дважды.
Можно ли ограничить расход токенов?
Да, в параметрах проекта. Лимит проверяется перед стартом каждого агента, а не по факту — прогон не уйдёт в минус.
Что происходит с артефактами после удаления?
Удаляются вместе с прогоном. Резервная копия хранится семь суток, восстановление — через поддержку.
Разметка
<div class="inst-accordion">
  <details class="inst-accordion-item" name="faq" open>
    <summary class="inst-accordion-head">Почему прогон занял 42 секунды?</summary>
    <div class="inst-accordion-body">Три прохода расстановки ресурсов плюс запекание навмеша.
      Основное время ушло на валидацию путей, которая перезапускалась дважды.</div>
  </details>
  <details class="inst-accordion-item" name="faq">
    <summary class="inst-accordion-head">Можно ли ограничить расход токенов?</summary>
    <div class="inst-accordion-body">Да, в параметрах проекта. Лимит проверяется перед стартом
      каждого агента, а не по факту — прогон не уйдёт в минус.</div>
  </details>
  <details class="inst-accordion-item" name="faq">
    <summary class="inst-accordion-head">Что происходит с артефактами после удаления?</summary>
    <div class="inst-accordion-body">Удаляются вместе с прогоном. Резервная копия хранится семь
      суток, восстановление — через поддержку.</div>
  </details>
</div>

Использование

<div class="inst-accordion">
  <details class="inst-accordion-item" name="faq" open>
    <summary class="inst-accordion-head">Заголовок</summary>
    <div class="inst-accordion-body">Содержимое</div>
  </details>
  <details class="inst-accordion-item" name="faq">
    <summary class="inst-accordion-head">Второй</summary>
    <div class="inst-accordion-body">Содержимое</div>
  </details>
</div>
Что Обязательно Почему
<details> под inst-accordion-item да Раскрытие, клавиатура и состояние open — от платформы
<summary> под inst-accordion-head да Только <summary> фокусируем и переключает <details>
Общий name да, для аккордеона Делает группу взаимоисключающей. Без него секции независимы
Прямое вложение да Правила открытой секции записаны через >: заголовок обязан быть прямым потомком <details>
Настоящий заголовок внутри <summary> нет, но обычно да <summary> сам по себе в оглавление страницы не попадает

Когда использовать

Используйте Возьмите другое
Длинные разделы содержимого, из которых читают один Равноправные виды одного объектавкладки: у них видно все названия сразу и нет прыжка высоты
Вопросы и ответы, справка, редко нужные подробности Вызов инструмента с телом выводашаг агента: это другая работа, у него есть фаза и длительность
Секции формы, которые заполняют по очереди Всё, что нужно видеть одновременнопанели в колонку: аккордеон прячет то, что сравнивают
Свёрнутые подробности внутри одного блока Одиночный сворачиваемый блок — просто <details> без группы: inst-accordion предполагает группу

Устройство

Элемент Класс Тег
Контейнер группы inst-accordion <div>
Секция inst-accordion-item <details>
Заголовок-переключатель inst-accordion-head <summary>
Содержимое inst-accordion-body <div>

Шеврон рисуется псевдоэлементом заголовка и поворачивается на 180° при открытии — своего класса у него нет и разметки он не требует. Нативный треугольник <summary> снят.

Волосок под заголовком появляется только у открытой секции (.inst-accordion-item[open] > .inst-accordion-head): у закрытой отделять нечего.

Поведение

Взаимное исключение

Общий атрибут name на элементах <details> делает группу взаимоисключающей: открытие второй секции закрывает первую.

Что нужно Как
Открыта ровно одна секция Общий name на всех <details>
Открыто сколько угодно name не ставить
Какая открыта при загрузке open на нужном <details>

Уберите name — и секции станут независимыми, открывать можно сколько угодно. Это единственная разница между «аккордеоном» и «списком раскрывашек», и она в один атрибут.

Пример
Без name — открываются независимо
Эту можно оставить открытой и открыть следующую.
Вторая секция
Первая при этом не закроется.
Разметка
<div class="inst-accordion">
  <details class="inst-accordion-item" open>
    <summary class="inst-accordion-head">Без name — открываются независимо</summary>
    <div class="inst-accordion-body">Эту можно оставить открытой и открыть следующую.</div>
  </details>
  <details class="inst-accordion-item">
    <summary class="inst-accordion-head">Вторая секция</summary>
    <div class="inst-accordion-body">Первая при этом не закроется.</div>
  </details>
</div>

Правила

Так Нативный details с общим name

Взаимное исключение, раскрытие, клавиатура и поиск по странице приходят от платформы. JS не нужен вовсе.

Не так Своя раскрывашка на div

Она теряет aria-expanded, поиск по странице, раскрытие при печати и требует скрипта ради того, что уже работает.

Так Заголовок нужного уровня внутри summary

Если секции — разделы страницы, <summary> сам в оглавление не попадёт.

Не так Аккордеон для того, что сравнивают

Он прячет ровно то, между чем ищут различия. Нужны панели в колонку или вкладки.

Доступность

Клавиатура Tab до заголовка, Enter или Space — переключение. Всё нативное, кит ничего не перехватывает
Роль и состояние <summary> сам объявляет себя переключателем и сообщает, раскрыт ли раздел. Своего aria-expanded ставить не надо и не нужно
Поиск по странице Содержимое закрытой секции находится браузерным поиском, и секция раскрывается сама — это поведение <details>, ради него нативный элемент и взят
Заголовок Если секции — разделы страницы, вложите в <summary> настоящий заголовок нужного уровня: <summary> сам по себе в оглавление не попадает
Цель нажатия Заголовок нажимается целиком, от края до края: --control-h-lg в высоту
Уменьшенное движение Поворот шеврона схлопывается вместе со всеми переходами
Печать Закрытые секции раскрываются на листе: закрытый <details> на бумаге — невосстановимо потерянное содержимое

API

ИмяЗначениеЧто делает
класс
inst-accordionКонтейнер. Колонка секций с зазором --space-1
inst-accordion-itemСекция. Рамка, радиус, overflow: hidden
inst-accordion-headЗаголовок. Высота от --control-h-lg, шеврон у дальнего края
inst-accordion-bodyСодержимое
токен
--space-12px
--space-36px
--pad-cell-xvar(--space-4)
--pad-panelvar(--space-5)
--gap-inlinevar(--space-4)
--control-h-lg38px
--radius-md7px
--hairline1px
--borderlight-dark(oklch(0 0 0 / 0.12), oklch(1 0 0 / 0.11))
--border-subtlelight-dark(oklch(0 0 0 / 0.07), oklch(1 0 0 / 0.06))
--surface-raisedlight-dark(var(--n-0), var(--n-12))
--surface-hoverlight-dark(oklch(0 0 0 / 0.035), oklch(1 0 0 / 0.045))
--size-chevron10px
--text-mutedlight-dark(var(--n-8), var(--n-6))
--text-sm0.8125rem
--weight-medium500
--dur-180ms
--ease-outcubic-bezier(0.22, 0.61, 0.36, 1)

Почему кит устроен именно так — конституция · Открытый код под MIT, github.com/keshon/instrument