Всем привет! Мы продолжаем создавать элементы пользовательского интерфейса (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; // скрываем контент
}
}
Спасибо вам огромное и за урок и за код, очень простое и понятное объяснение!
Шикарный пример, очень всё понятно, плюс для меня новые функции closest и nextElementSibling
Спасибо большое!