Всем привет! Мы продолжаем создавать элементы пользовательского интерфейса (UI). Сегодня коснемся такой темы, как аккордеоны. Аккордеон позволяет скрывать часть контента и при нажатии на бокс у нас плавно раскрывается весь контент.

В этой статье рассмотрим аккордеоны с минималистичным дизайном, чтобы не усложнять код. Вы сможете в дальнейшем их стилизовать под себя.

Разметка аккордеона

Все элементы аккордеона находится в контейнере (div с классом container). В элементе box находится содержимое одного элемента. Label — это, то что мы видим (метка), content — это, то что скрыто (контент).

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="reset.css" />
    <link rel="stylesheet" href="style.css" />
    <title>Document</title>
  </head>
  <body>
    <div class="container">
      <div class="box">
        <div class="label">Box One</div>
        <div class="content">
          <p>
            Lorem ipsum dolor, sit amet consectetur adipisicing elit. Esse
            adipisci ex impedit itaque labore. Dolorum tempore ipsum autem
            molestias corrupti possimus voluptate, quos accusamus esse maiores
            dolorem qui eaque facilis nemo nulla, amet excepturi laborum eveniet
            eligendi aperiam nostrum culpa. Possimus architecto saepe quidem
            quam molestiae! Incidunt deleniti quas dolore temporibus nisi
            voluptates non dolores excepturi dicta ducimus asperiores quam,
            neque totam ratione reiciendis consequatur a quasi inventore vero
            doloribus commodi? Dolorem consequatur laborum blanditiis.
          </p>
        </div>
      </div>
      <div class="box">
        <div class="label">Box Two</div>
        <div class="content">
          <p>
            Lorem ipsum dolor, sit amet consectetur adipisicing elit. Esse
            adipisci ex impedit itaque labore. Dolorum tempore ipsum autem
            molestias corrupti possimus voluptate, quos accusamus esse maiores
            dolorem qui eaque facilis nemo nulla, amet excepturi laborum eveniet
            eligendi aperiam nostrum culpa. Possimus architecto saepe quidem
            quam molestiae! Incidunt deleniti quas dolore temporibus nisi
            voluptates non dolores excepturi dicta ducimus asperiores quam,
            neque totam ratione reiciendis consequatur a quasi inventore vero
            doloribus commodi? Dolorem consequatur laborum blanditiis.
          </p>
        </div>
      </div>
      <div class="box">
        <div class="label">Box Three</div>
        <div class="content">
          <p>
            Lorem ipsum dolor, sit amet consectetur adipisicing elit. Esse
            adipisci ex impedit itaque labore. Dolorum tempore ipsum autem
            molestias corrupti possimus voluptate, quos accusamus esse maiores
            dolorem qui eaque facilis nemo nulla, amet excepturi laborum eveniet
            eligendi aperiam nostrum culpa. Possimus architecto saepe quidem
            quam molestiae! Incidunt deleniti quas dolore temporibus nisi
            voluptates non dolores excepturi dicta ducimus asperiores quam,
            neque totam ratione reiciendis consequatur a quasi inventore vero
            doloribus commodi? Dolorem consequatur laborum blanditiis.
          </p>
        </div>
      </div>
      <div class="box">
        <div class="label">Box Four</div>
        <div class="content">
          <p>
            Lorem ipsum dolor, sit amet consectetur adipisicing elit. Esse
            adipisci ex impedit itaque labore. Dolorum tempore ipsum autem
            molestias corrupti possimus voluptate, quos accusamus esse maiores
            dolorem qui eaque facilis nemo nulla, amet excepturi laborum eveniet
            eligendi aperiam nostrum culpa. Possimus architecto saepe quidem
            quam molestiae! Incidunt deleniti quas dolore temporibus nisi
            voluptates non dolores excepturi dicta ducimus asperiores quam,
            neque totam ratione reiciendis consequatur a quasi inventore vero
            doloribus commodi? Dolorem consequatur laborum blanditiis.
          </p>
        </div>
      </div>
    </div>
    <script src="app.js"></script>
  </body>
</html>

Стилизация аккордеона

Все комментарии в самом коде.

@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

*,
*::after,
*::before {
  box-sizing: inherit;
}

body {
  font-family: "Roboto", sans-serif;
  font-size: 16px;
  line-height: 1.2;
  width: 100%;
  min-height: 100vh;
  background-color: rgb(232, 232, 255);
  display: flex;
  justify-content: center;
}

.container {
  padding: 30px;
  max-width: 800px;
}

.container .box {
  position: relative;
  margin-bottom: 20px; /* Нижний отступ между элементами аккордеона */
}

.container .box:last-child {
  margin-bottom: 0; /* Для последнего элемента нижний отступ убираем */
}

.container .box .label {
  position: relative;
  padding: 20px; /* Внутренний отступ для видимой части */
  background-color: darkblue; /* Цвет элемента аккордеона */
  color: #fff; /* Цвет шрифта элемента аккордеона */
  cursor: pointer; /* Меняем курсор при наведении */
}

.container .box .label::after {
  content: "+"; /* Задаем иконку "+" для элемента аккордеона */
  position: absolute;
  top: 50%; /* Выравнивание по центру */
  transform: translateY(-50%);
  right: 20px;
  font-size: 25px;
  font-weight: bold;
}

.container .box.active .label::after {
  content: "\2014"; /* Меняем иконку на "-" при нажатии на элемент */
}

.container .box .content {
  position: relative;
  background-color: #fff; /* Цвет фона контента */
  overflow: hidden;
  max-height: 0; /* Скрываем контент */
  transition: 0.3s; /* Для плавности анимации */
}

.container .box .content p {
  padding: 20px;
}

Скрипт для работы аккордеона

Комментарии в коде.

const boxes = Array.from(document.querySelectorAll(".box")); // считываем все элементы аккордеона в массив

boxes.forEach((box) => {
  box.addEventListener("click", boxHandler); // при нажатии на бокс вызываем ф-ию boxHanlder
});

function boxHandler(e) {
  e.preventDefault(); // сбрасываем стандартное поведение
  let currentBox = e.target.closest(".box"); // определяем текущий бокс
  let currentContent = e.target.nextElementSibling; // находим скрытый контент
  currentBox.classList.toggle("active"); // присваиваем ему активный класс
  if (currentBox.classList.contains("active")) {
    // если класс активный ..
    currentContent.style.maxHeight = currentContent.scrollHeight + "px"; // открываем контент
  } else {
    // в противном случае
    currentContent.style.maxHeight = 0; // скрываем контент
  }
}
 

Комментарии

2

Без регистрации и смс

  • Elena Titlyanova:

    Спасибо вам огромное и за урок и за код, очень простое и понятное объяснение!

  • Инна:

    Шикарный пример, очень всё понятно, плюс для меня новые функции closest и nextElementSibling

    Спасибо большое!