Плавное изменение высоты блока

Рассмотрим два случая, с которыми мы можем столкнуться при необходимости плавно изменить высоту блока - когда известна максимальная высота блока и когда нет.

Начнем с более сложного, но и более распространенного случая.

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

В html-файл вставляем следующие строки:

<div class="smooth-open short">
    Здесь много-много текста
</div>
<div class="show-more"></div>

<script>
    document.addEventListener('DOMContentLoaded', function() {
        document.querySelectorAll('.smooth-open.short').forEach((e) => {
            if (e.offsetHeight == e.scrollHeight) {
                e.classList.remove('short')
                if (e.nextElementSibling.classList.contains('show-more')) e.nextElementSibling.style.display = 'none'
            } else {
                e.dataset.minHeight = e.offsetHeight + 'px'
                e.dataset.maxHeight = e.scrollHeight + 'px'
                e.style.transitionDuration = (e.scrollHeight - e.offsetHeight) + 'ms'
            }
        })
    })

    document.querySelectorAll('.show-more').forEach((e) => {
        e.addEventListener('click', function () {
            const div = this.previousElementSibling

            if ( div.classList.contains('short') ) div.style.height = div.dataset.maxHeight
            else div.style.height = div.dataset.minHeight

            div.classList.toggle('short')
        }, false)
    })
</script>

И в css - следующие:

.smooth-open {
    overflow: hidden;
    transition-property: height;
}
.smooth-open.short {
    height: 160px;
    -webkit-mask-image: linear-gradient(to bottom, black 65%, transparent 100%);
    mask-image: linear-gradient(to bottom, black 65%, transparent 100%);
}
.show-more {
    padding: 20px 0 40px 0;
}
.show-more::before {
    content: 'Скрыть';
    cursor: pointer;
}
.short + .show-more::before {
    content: 'Показать больше';
}
.show-more::after {
    content: '<';
    cursor: pointer;
    display: inline-block;
    transform: rotate(90deg) scale(1, 2);
    margin-left: 10px;
}
.short +.show-more::after {
    content: '>';
}

Готово.

Переходим к простому случаю - когда нам известна максимальная высота блока.

В html-файл вставляем следующие строки:

<div class="smooth-open short">
    Здесь много-много текста
</div>
<div class="show-more" onclick="this.previousElementSibling.classList.toggle('short')"></div>

И в css - следующие:

.smooth-open {
    height: 450px;
    transition: height .6s;
    overflow: hidden;
}
.smooth-open.short {
    height: 160px;
}
.show-more::before {
    content: 'Скрыть';
    cursor: pointer;
}
.short + .show-more::before {
    content: 'Показать больше';
}

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *