Как называется такой выпадающий текст?
Ответы (5 шт):
Это называется collapsible или accordion:
const handleClick = () => {
document.querySelector("div").classList.toggle("hide")
}
document.querySelector("a").addEventListener("click", handleClick)
a {
display: block;
background-color: #f2f2f2;
padding: 10px 20px;
cursor: pointer;
}
div {
background-color: #f2f2f2;
padding: 10px 20px;
}
.hide {
display: none;
}
<a>Облась по которой нужно нажать что бы развернуть</a>
<div class="hide">Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs. The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum et Malorum for use in a type specimen book.</div>
Вот, пример с анимациями разворачивания.
Добавил комментарии в JavaScript.
Тут происходит анимация за счёт transition
В CSS свойство height может анимироваться через transition только если его задать в px.
Т.е., если у элемента будет стоять transition: height 0.2s linear, и мы ему будем менять свойство height с auto на 0, то не будет анимации. Поэтому здесь нужен JavaScript, чтобы просто задавать эту высоту в пикселях
const accordion__items = [...document.querySelectorAll('.accordion__item')]; // Получаю элементы .accordion__item
accordion__items.forEach((item) => { // прохожусь по ним в цикле
const btn = item.querySelector('.accordion__header__img'); //Нахожу у элемента кружок, в котором будет плюс или минус
const text = item.querySelector('.accordion__text__wrapper'); // Нахожу обертку у элемента, которую буду уменьшать
let height; // Высота обертки элемента
resize(); // Вызываем просчёт высоты и задаём CSS стили для обёртки
if (!item.classList.contains('active')) { // если у текущего элемента аккордеона нету класс .active
text.style.height = '0px'; // задать обертке нулевую высоту
}
function addOrRemoveHeight(height) {
if (item.classList.contains('active')) { // если у текущего элемента аккордеона есть класс .active
text.style.height = height + 'px'; // задать высоту, которую мы просчитали перед этим в переменной height
} else {
text.style.height = '0px'; // Иначе задать нулевую высоту
}
}
function resize() {
text.style.height = 'auto'; // Задать элементу высоту auto, чтобы мы могли её посчитать, потому что мы её могли обнулить в CSS стилях
height = text.scrollHeight; // Запоминаем высоту элемента в переменную
addOrRemoveHeight(height); // Вызываем функцию, которая добавляет в CSS высоту элементу
}
window.addEventListener('resize', resize); // ставим слушатель события resize на функцию resize
btn.addEventListener('click', () => { // при клике на кружок, выполнять анонимную функцию
item.classList.toggle('active'); // удаляем класс .active если он есть, иначе добавляем
addOrRemoveHeight(height); // Вызываем функцию, которая добавляет в CSS высоту элементу
});
});
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;700&family=Raleway:wght@400;500;700&display=swap');
*,
*::before,
*::after {
box-sizing: border-box;
padding: 0px;
margin: 0px;
}
:root {
--red: #ff0036;
--transitionDuration: 0.2s;
--transitionTimingFunction: linear;
--time: var(--transitionDuration) var(--transitionTimingFunction);
}
body {
font-size: 16px;
font-family: 'Raleway', sans-serif;
}
.container {
max-width: 800px;
width: 100%;
display: block;
margin: 0 auto;
padding: 0 15px;
}
.accordion {
--gray: #e7e7e7;
}
.accordion__item {
--backgroundColor: #f7f7f7;
}
.accordion__item:not(:last-child) {
margin-bottom: 10px;
}
.accordion__header {
display: flex;
align-items: center;
border: 1px solid var(--gray);
user-select: none;
background-color: var(--backgroundColor);
}
.accordion__header__title {
padding-right: 10px;
transition: color var(--time);
}
.accordion__item.active {
height: 152;
}
.accordion__item.active .accordion__header__title {
color: var(--red)
}
.accordion__header__img {
margin-right: 20px;
border-right: 1px solid var(--gray);
padding: 10px;
cursor: pointer;
}
.accordion__header__img-circle {
border: 1px solid #505050;
padding: 10px;
border-radius: 50%;
position: relative;
display: flex;
align-items: center;
justify-content: center;
transition: border-color var(--time);
}
.accordion__item.active .accordion__header__img-circle {
border-color: var(--red);
}
.accordion__header__img-circle::before,
.accordion__header__img-circle::after {
content: "";
position: absolute;
display: block;
width: 60%;
height: 2px;
background-color: #505050;
transition: background-color var(--time), transform var(--time);
}
.accordion__item.active .accordion__header__img-circle::before,
.accordion__item.active .accordion__header__img-circle::after {
background-color: var(--red);
}
.accordion__item.active .accordion__header__img-circle::before {
transform: rotate(0deg);
}
.accordion__header__img-circle::before {
transform: rotate(90deg);
}
.accordion__text {
border: 1px solid var(--gray);
border-top: none;
padding: 12px;
}
.accordion__text__wrapper {
overflow: hidden;
height: 0px;
background-color: var(--backgroundColor);
transition: height var(--time);
}
<div class="container">
<div class="accordion">
<div class="accordion__item active">
<div class="accordion__header">
<div class="accordion__header__img">
<div class="accordion__header__img-circle">
</div>
</div>
<div class="accordion__header__title">Who is creativia</div>
</div>
<div class="accordion__text__wrapper">
<div class="accordion__text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et dolor justo. Phasellus eu ligula ac nisl volutpat tincidunt. Vestibulum vitae rhoncus odio Fusce sed enim erat. Mauris dictum lorem eu tortor porta placerat. Suspendisse ac vestibulum eros.
</div>
</div>
</div>
<!-- .accordion__item -->
<div class="accordion__item">
<div class="accordion__header">
<div class="accordion__header__img">
<div class="accordion__header__img-circle">
</div>
</div>
<div class="accordion__header__title">Experiences</div>
</div>
<div class="accordion__text__wrapper">
<div class="accordion__text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et dolor justo. Phasellus eu ligula ac nisl volutpat tincidunt. Vestibulum vitae rhoncus odio Fusce sed enim erat. Mauris dictum lorem eu tortor porta placerat. Suspendisse ac vestibulum eros.
</div>
</div>
</div>
<!-- .accordion__item -->
<div class="accordion__item">
<div class="accordion__header">
<div class="accordion__header__img">
<div class="accordion__header__img-circle">
</div>
</div>
<div class="accordion__header__title">Learn more</div>
</div>
<div class="accordion__text__wrapper">
<div class="accordion__text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et dolor justo. Phasellus eu ligula ac nisl volutpat tincidunt. Vestibulum vitae rhoncus odio Fusce sed enim erat. Mauris dictum lorem eu tortor porta placerat. Suspendisse ac vestibulum eros.
</div>
</div>
</div>
<!-- .accordion__item -->
</div>
</div>
На чистом CSS
Суть идеи заключается в том, чтобы спрятать чекбокс и менять его состояние путем клика на заголовок одной из строк. Чекбокс в свою очередь выступает в роли переключателя содержимого, если он :checked, то показываем элемент, в обычном состоянии просто скрываем через max-height: 0 и visibility: hidden. Почему именно max-height: 0 ? Потому-что только так можно анимировать высоту контента без JS'a. Т.к. мы не знаем максимальную высоту, мы укажем максимально допустимую для этого контента, то есть max-height: 1000px.
Про анимацию высоты на css сказано в этой статье: how-can-i-transition-height-0-to-height-auto-using-css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
img {
max-width: 100%;
max-height: 100%;
}
body {
font-family: monospace, sans-serif;
overflow-y: scroll;
}
.accordion__container {
margin: 0 auto;
max-width: 70%;
}
.accordion__container .accordion__row {
width: 100%;
box-shadow: 0 15px 15px #f6f6f6;
padding: 20px;
}
.accordion__container .accordion__row input {
display: none;
}
.accordion__container .accordion__row input:checked ~ section {
max-height: 1000px;
visibility: visible;
opacity: 1;
transition: visibility 0.5s 0s, opacity 0.5s, max-height 0.5s;
}
.accordion__container .accordion__row input:checked ~ label .arrow {
transform: rotate(-180deg);
}
.accordion__container .accordion__row label {
display: flex;
height: 60px;
align-items: center;
}
.accordion__container .accordion__row label .icon, .accordion__container .accordion__row label .arrow {
flex-shrink: 0;
}
.accordion__container .accordion__row label .icon {
width: 40px;
height: 100%;
margin-right: 20px;
display: flex;
}
.accordion__container .accordion__row label .arrow {
width: 20px;
margin-left: 20px;
transition: transform 0.4s;
}
.accordion__container .accordion__row label .name {
width: 100%;
font-size: 20px;
font-weight: 900;
}
.accordion__container .accordion__row section {
max-height: 0;
display: flex;
visibility: hidden;
opacity: 0;
transition: visibility 0.5s 0s, opacity 0.5s, max-height 0.5s;
}
.accordion__container .accordion__row section .image {
flex-shrink: 0;
width: 30%;
margin-right: 4%;
}
<div class="accordion__container">
<div class="accordion__row">
<input type="checkbox" id="accordion__1">
<label for="accordion__1">
<div class="icon">
<img src="https://image.flaticon.com/icons/svg/478/478544.svg" alt="">
</div>
<div class="name">
<h4>Statistics</h4>
</div>
<div class="arrow">
<img src="https://image.flaticon.com/icons/svg/318/318225.svg" alt="">
</div>
</label>
<section>
<div class="image">
<img src="https://i2ds.org/wp-content/uploads/2020/03/503930-636173965766935316-16x9-1.jpg" alt="">
</div>
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Earum, excepturi molestias sapiente molestiae culpa sequi laudantium nihil minus voluptates modi eius, corporis hic nulla, ab laboriosam voluptatem esse. Quaerat, nostrum.
<br>
<br>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Omnis, sint numquam iure.
</div>
</section>
</div>
<div class="accordion__row">
<input type="checkbox" id="accordion__2">
<label for="accordion__2">
<div class="icon">
<img src="https://image.flaticon.com/icons/svg/558/558346.svg" alt="">
</div>
<div class="name">
<h4>Inbox</h4>
</div>
<div class="arrow">
<img src="https://image.flaticon.com/icons/svg/318/318225.svg" alt="">
</div>
</label>
<section>
<div class="image">
<img src="https://i2ds.org/wp-content/uploads/2020/03/503930-636173965766935316-16x9-1.jpg" alt="">
</div>
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Earum, excepturi molestias sapiente molestiae culpa sequi laudantium nihil minus voluptates modi eius, corporis hic nulla, ab laboriosam voluptatem esse. Quaerat, nostrum.
<br>
<br>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Omnis, sint numquam iure.
</div>
</section>
</div>
</div>
В Chrome 129 появилась возможность анимировать CSS свойства без точных значений. Теперь можно анимировать height: auto без каких либо костылей. Мой прошлый ответ был написан как раз с костылём для решения проблем анимации height: auto
Написание interpolate-size: allow-keywords для :root устанавливает новое поведение анимации для всей страницы
:root {
interpolate-size: allow-keywords;
}
function getAccordionNodes() {
const accordionItemNodes = Array.from(document.querySelectorAll('.accordion__item'));
return accordionItemNodes.map(accordionItemNode => ({
accordionItemNode: accordionItemNode,
accordionHeaderNode: accordionItemNode.querySelector('.accordion__header')
}));
}
function logicAccordion() {
const accordionNodes = getAccordionNodes();
for (const { accordionItemNode, accordionHeaderNode } of accordionNodes) {
accordionHeaderNode.addEventListener('click', () => {
accordionItemNode.classList.toggle('accordion__item_active');
});
}
}
logicAccordion();
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;700&family=Raleway:wght@400;500;700&display=swap');
*,
*::before,
*::after {
box-sizing: border-box;
padding: 0px;
margin: 0px;
}
:root {
--red: #ff0036;
--transitionDuration: 0.2s;
--transitionTimingFunction: linear;
--time: var(--transitionDuration) var(--transitionTimingFunction);
interpolate-size: allow-keywords;
}
body {
font-size: 16px;
font-family: 'Raleway', sans-serif;
}
.container {
max-width: 800px;
width: 100%;
display: block;
margin: 0 auto;
padding: 0 15px;
}
.accordion {
--gray: #e7e7e7;
}
.accordion__item {
--backgroundColor: #f7f7f7;
}
.accordion__item:not(:last-child) {
margin-bottom: 10px;
}
.accordion__header {
display: flex;
align-items: center;
border: 1px solid var(--gray);
user-select: none;
background-color: var(--backgroundColor);
cursor: pointer;
}
.accordion__header__title {
padding-right: 10px;
transition: color var(--time);
}
.accordion__item_active .accordion__header__title {
color: var(--red)
}
.accordion__header__img {
margin-right: 20px;
border-right: 1px solid var(--gray);
padding: 10px;
}
.accordion__header__img-circle {
border: 1px solid #505050;
padding: 10px;
border-radius: 50%;
position: relative;
display: flex;
align-items: center;
justify-content: center;
transition: border-color var(--time);
}
.accordion__item_active .accordion__header__img-circle {
border-color: var(--red);
}
.accordion__header__img-circle::before,
.accordion__header__img-circle::after {
content: "";
position: absolute;
display: block;
width: 60%;
height: 2px;
background-color: #505050;
transition: background-color var(--time), transform var(--time);
}
.accordion__item_active .accordion__header__img-circle::before,
.accordion__item_active .accordion__header__img-circle::after {
background-color: var(--red);
}
.accordion__item_active .accordion__header__img-circle::before {
transform: rotate(0deg);
}
.accordion__header__img-circle::before {
transform: rotate(90deg);
}
.accordion__text {
border: 1px solid var(--gray);
border-top: none;
padding: 12px;
}
.accordion__text__wrapper {
overflow: hidden;
height: 0px;
background-color: var(--backgroundColor);
transition: height var(--time);
}
.accordion__item_active .accordion__text__wrapper {
height: auto;
}
.accordion__header:target {
background-color: black;
}
<div class="container">
<div class="accordion">
<div class="accordion__item accordion__item_active">
<div class="accordion__header">
<div class="accordion__header__img">
<div class="accordion__header__img-circle">
</div>
</div>
<div class="accordion__header__title">Who is creativia</div>
</div>
<div class="accordion__text__wrapper">
<div class="accordion__text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Ut et dolor justo.
Phasellus eu ligula ac nisl volutpat tincidunt.
Vestibulum vitae rhoncus odio Fusce sed enim erat.
Mauris dictum lorem eu tortor porta placerat.
Suspendisse ac vestibulum eros.
</div>
</div>
</div> <!-- .accordion__item -->
<div class="accordion__item">
<div class="accordion__header">
<div class="accordion__header__img">
<div class="accordion__header__img-circle">
</div>
</div>
<div class="accordion__header__title">Experiences</div>
</div>
<div class="accordion__text__wrapper">
<div class="accordion__text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Ut et dolor justo.
Phasellus eu ligula ac nisl volutpat tincidunt.
Vestibulum vitae rhoncus odio Fusce sed enim erat.
Mauris dictum lorem eu tortor porta placerat.
Suspendisse ac vestibulum eros.
</div>
</div>
</div> <!-- .accordion__item -->
<div class="accordion__item">
<div class="accordion__header">
<div class="accordion__header__img">
<div class="accordion__header__img-circle">
</div>
</div>
<div class="accordion__header__title">Learn more</div>
</div>
<div class="accordion__text__wrapper">
<div class="accordion__text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Ut et dolor justo.
Phasellus eu ligula ac nisl volutpat tincidunt.
Vestibulum vitae rhoncus odio Fusce sed enim erat.
Mauris dictum lorem eu tortor porta placerat.
Suspendisse ac vestibulum eros.
</div>
</div>
</div> <!-- .accordion__item -->
</div>
</div>
В фреймворке бутстрап это называется аккордионом. https://getbootstrap.com/docs/5.0/components/accordion/
И работает на основе коллапса: https://getbootstrap.com/docs/5.0/components/collapse/
