Аккордеон на чистом JavaScript и CSS

Как при помощи простого кода на JavaScript, CSS и минимальной разметки HTML реализовать удобный аккордеон? Аккордеон позволяет скрывать и раскрывать содержимое, экономить место на странице и улучшать пользовательский опыт.

1. Разметка HTML

HTML
<div class="accordion">
    <div class="accordion__item accordion-item">
        <div class="accordion-item__header">
            <h3>Далеко-далеко, за словесными.</h3>
        </div>
        <div class="accordion-item__body">
            <p>Далеко-далеко за словесными горами в стране гласных, и согласных живут рыбные тексты. Свой взобравшись
                агентство даль живет щеке большой дал однажды коварный знаках грустный заглавных инициал по всей, лучше
                заголовок переписали переписывается заманивший.</p>
            <p>Далеко-далеко за словесными горами в стране гласных, и согласных живут рыбные тексты. Свой взобравшись
                агентство даль живет щеке большой дал однажды коварный знаках грустный заглавных инициал по всей, лучше
                заголовок переписали переписывается заманивший.</p>
        </div>
    </div>
    <div class="accordion__item accordion-item">
        <div class="accordion-item__header">
            <h3>Далеко-далеко, за словесными.</h3>
        </div>
        <div class="accordion-item__body">
            <p>Далеко-далеко за словесными горами в стране гласных, и согласных живут рыбные тексты. Свой взобравшись
                агентство даль живет щеке большой дал однажды коварный знаках грустный заглавных инициал по всей, лучше
                заголовок переписали переписывается заманивший.</p>
            <p>Далеко-далеко за словесными горами в стране гласных, и согласных живут рыбные тексты. Свой взобравшись
                агентство даль живет щеке большой дал однажды коварный знаках грустный заглавных инициал по всей, лучше
                заголовок переписали переписывается заманивший.</p>
        </div>
    </div>
    <div class="accordion__item accordion-item">
        <div class="accordion-item__header">
            <h3>Далеко-далеко, за словесными.</h3>
        </div>
        <div class="accordion-item__body">
            <p>Далеко-далеко за словесными горами в стране гласных, и согласных живут рыбные тексты. Свой взобравшись
                агентство даль живет щеке большой дал однажды коварный знаках грустный заглавных инициал по всей, лучше
                заголовок переписали переписывается заманивший.</p>
            <p>Далеко-далеко за словесными горами в стране гласных, и согласных живут рыбные тексты. Свой взобравшись
                агентство даль живет щеке большой дал однажды коварный знаках грустный заглавных инициал по всей, лучше
                заголовок переписали переписывается заманивший.</p>
        </div>
    </div>
    <div class="accordion__item accordion-item">
        <div class="accordion-item__header">
            <h3>Далеко-далеко, за словесными.</h3>
        </div>
        <div class="accordion-item__body">
            <p>Далеко-далеко за словесными горами в стране гласных, и согласных живут рыбные тексты. Свой взобравшись
                агентство даль живет щеке большой дал однажды коварный знаках грустный заглавных инициал по всей, лучше
                заголовок переписали переписывается заманивший.</p>
            <p>Далеко-далеко за словесными горами в стране гласных, и согласных живут рыбные тексты. Свой взобравшись
                агентство даль живет щеке большой дал однажды коварный знаках грустный заглавных инициал по всей, лучше
                заголовок переписали переписывается заманивший.</p>
        </div>
    </div>
    <div class="accordion__item accordion-item">
        <div class="accordion-item__header">
            <h3>Далеко-далеко, за словесными.</h3>
        </div>
        <div class="accordion-item__body">
            <p>Далеко-далеко за словесными горами в стране гласных, и согласных живут рыбные тексты. Свой взобравшись
                агентство даль живет щеке большой дал однажды коварный знаках грустный заглавных инициал по всей, лучше
                заголовок переписали переписывается заманивший.</p>
            <p>Далеко-далеко за словесными горами в стране гласных, и согласных живут рыбные тексты. Свой взобравшись
                агентство даль живет щеке большой дал однажды коварный знаках грустный заглавных инициал по всей, лучше
                заголовок переписали переписывается заманивший.</p>
        </div>
    </div>
</div>
  • Внешний контейнер имеет класс .accordion.
  • Каждый пункт аккордеона — это элемент с классами .accordion__item и .accordion-item.
  • Внутри у пункта два блока:
    • .accordion-item__header — кликабельная шапка, содержащая заголовок.
    • .accordion-item__body — скрытая по умолчанию область с подробным содержимым.

2. Стили CSS

CSS
.accordion {
  user-select: none;
}
.accordion-item__body {
  transition: var(--transition);
  overflow: hidden;
  opacity: 0;
}
.accordion-item {
  cursor: pointer;
  display: grid;
  grid-template-rows: min-content minmax(0, 0fr);
  transition: var(--transition);
}
.accordion-item.show {
  grid-template-rows: min-content minmax(0, 1fr);
}
.accordion-item.show .accordion-item__body {
  opacity: 1;
}
  • .accordion-item изначально имеет две строки сетки: шапка под размер контента, а тело с высотой 0.
  • При добавлении класса .show второму ряду даётся пропорция 1fr, чтобы тело увеличивалось по содержимому.
  • .accordion-item__body скрыто благодаря opacity: 0 и overflow: hidden, а анимация происходит за счёт transition.

3. Скрипт JavaScript

JavaScript
function Accordion(selector){
    let accordion = document.querySelector(selector);
    let accordionItems = accordion.querySelectorAll(selector + ' > *');
    accordionItems.forEach((item) => {
        item.onclick = function () {
            this.classList.toggle('show');
            this.classList.add('active');
            accordionItems.forEach((everyItem) => {
                if (!everyItem.classList.contains('active')) {
                    everyItem.classList.remove('show');
                }
            });
            this.classList.remove('active');
        }
    });
}

Пояснение работы скрипта

  1. Выборка элементов
    Сначала находим контейнер по переданному селектору (.accordion) и все его прямые дочерние элементы (каждый пункт).
  2. Обработчик клика
    Для каждого пункта при клике:
    • toggle('show') — либо добавляет, либо убирает класс .show, тем самым раскрывая или сворачивая тело.
    • add('active') — временно помечает кликнутый пункт как «активный».
  3. Скрытие остальных пунктов
    Перебираем все пункты и у тех, что не имеют сейчас класса active, удаляем класс show. Таким образом, одновременно раскрытым остаётся только текущий пункт.
  4. Сброс флага active
    После того, как у всех остальных снят show, убираем у текущего пункта метку active, чтобы в следующий клик логика работала заново.

4. Шаги интеграции

  1. Подключите стили
    Вставьте CSS в отдельный файл (например, accordion.css) или в блок <style> на странице блога.
  2. Вставьте HTML-разметку
    Подготовьте секцию в редакторе, убедитесь, что все блоки .accordion-item оформлены внутри родительского контейнера с классом .accordion.
  3. Подключите скрипт
    Добавьте JavaScript-файл (например, accordion.js) перед закрывающим тегом </body> или используйте встроенный <script>.
  4. Проверьте работу
    Убедитесь, что пункты раскрываются по клику, а предыдущие автоматически сворачиваются.

5. Возможные улучшения

  • Иконки-стрелки в шапках, которые поворачиваются при раскрытии.
  • Опция множественного раскрытия, если нужно разрешить открывать сразу несколько пунктов.
  • ARIA-атрибуты для повышения доступности (например, aria-expanded).
  • Кастомизация анимации: изменение времени, функции ускорения, добавление задержки.

Таким образом, с помощью приведённого кода аккордеон на сайте настраивается быстро, без использования внешних библиотек. Подключите стили и скрипт, скопируйте структуру HTML — и готово!