Кастомизация интерактивных тегов details и summary

Хватит мучить JS там, где справится пара тегов

Признайся, сколько раз ты подключал целую библиотеку или писал потный JS-код с высчитыванием scrollHeight только для того, чтобы сделать обычный аккордеон? Дизайнеры рисуют красивые плавные раскрывашки, а стандартный HTML-тег details из коробки выглядит как привет из девяностых: дерганый, с уродливым стандартным треугольником и нулевой гибкостью. Мы привыкли думать, что details и summary — это для черновиков, а для продакшена нужно городить кастомные решения. Но на дворе почти 2026 год, и ситуация изменилась настолько, что пора выбрасывать костыли.

Как мы страдали раньше

Раньше кастомизация details была похожа на прогулку по минному полю. Чтобы убрать стандартную стрелочку, приходилось писать summary::-webkit-details-marker { display: none; }, что само по себе выглядит как костыль. А если ты хотел добавить анимацию раскрытия? Забудь. CSS не умеет анимировать height: auto, поэтому мы либо использовали max-height: 1000px (что ломало тайминги анимации), либо писали скрипты, которые измеряли высоту контента. К слову, когда контента внутри аккордеона очень много, не лишним будет вспомнить про оптимизацию рендеринга с помощью content-visibility, чтобы браузер не потел над отрисовкой скрытых блоков.

Как делать правильно в 2026 году

Сегодня details — это полноценный гибкий инструмент. Главный прорыв последних лет — это свойство interpolate-size: allow-keywords и новые возможности работы с состояниями. Теперь мы можем анимировать переход от закрытого к открытому состоянию прямо через CSS, не зная точной высоты контента. Мы используем псевдоэлемент ::marker для кастомизации иконки или вовсе скрываем его через list-style: none на теге summary (да, теперь это работает кроссбраузерно и легально).

Более того, современный подход подразумевает использование селектора [open] для стилизации. Мы можем плавно менять прозрачность контента, вращать кастомную иконку и даже управлять раскладкой через Grid. И не забудь про доступность: когда настраиваешь свои стили, убедись, что пользователь четко видит фокус. В этом тебе поможет доступность интерфейсов с псевдоклассом :focus-visible, чтобы не раздражать тех, кто пользуется клавиатурой.

Готовый сниппет кода

Лови чистый, современный код, который можно брать и вставлять в проект. Здесь минимум стилей, но максимум эффекта: плавная анимация стрелочки и контента без единой строчки JavaScript.


/* Стилизуем контейнер */
details {
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  background: #ffffff;
  transition: all 0.3s ease;
  overflow: hidden;
}

/* Убираем дефолтный маркер и делаем summary флексом */
summary {
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem;
  cursor: pointer;
  font-weight: 600;
  user-select: none;
}

/* Скрываем стандартный маркер в Safari */
summary::-webkit-details-marker {
  display: none;
}

/* Наша кастомная иконка */
summary::after {
  content: "→";
  transition: transform 0.3s ease;
}

/* Состояние при открытии */
details[open] summary::after {
  transform: rotate(90deg);
}

/* Плавное появление контента */
.content {
  padding: 0 1rem 1rem;
  opacity: 0;
  transform: translateY(-10px);
  transition: all 0.4s ease;
}

details[open] .content {
  opacity: 1;
  transform: translateY(0);
}

Частая ошибка новичков

Самый распространенный косяк — это попытка анимировать сам тег details. Помни: когда атрибут open добавляется к тегу, браузер мгновенно меняет его состояние, и контент появляется в DOM-дереве «резко». Чтобы анимация выглядела дорого и плавно, нужно анимировать именно внутренний обертку-контейнер (в нашем примере это .content). Если ты просто повесишь транзишн на details, ты получишь либо дерганый скачок, либо ничего. Также никогда не удаляй outline у summary просто так — если тебе не нравится стандартная синяя рамка, замени её на что-то более эстетичное, но не лишай пользователя навигации.

🔥 Больше фишек, готовых сниппетов и передовых подходов к CSS мы публикуем в нашем Telegram-канале. Подписывайтесь, чтобы не пропустить!

🚀 Прокачай свой код

Готовые CSS-сниппеты, разбор продвинутых фишек и эксклюзивные материалы — в нашем Telegram-канале.

Подписаться
error: Content is protected !!
Прокрутить вверх