Поява елементів при скролі
У цій статті ми розглянемо, як можна зробити плавну появу елементів під час прокручування сторінки.
Ми будемо використовувати css та трохи нативного js, без використання сторонніх бібліотек. Пристебніться!
Ви, напевно, бачили на багатьох сайтах красиву анімацію, де блоки з’являються в той момент, коли ви до них доскролили. Іноді вони з’являлися знизу вгору, іноді ліворуч, а іноді незрозуміло навіть як. Я покажу вам, як це робиться.
Анімація при скролі: створюємо html
Все починається з HTML. Давайте зробимо розмітку.
<div class="wrap">
<div class="element-big green"></div>
<div class="element-animation">
<span>Елемент, що з'являється</span>
</div>
<div class="element-big red"></div>
</div>
Ми тут створили два великі блоки та між ними текст. Два великі блоки нам потрібні, щоб вийшов скролл сторінки.
Зараз додамо css для них та ви все зрозумієте.
Поява елементів під час прокручування сторінки: додаємо початковий CSS
У CSS ми, по-перше, задамо великим блокам висоту, щоб у нас на сторінці з’явився скролл. Це потрібно лише для демонстрації.
А по-друге, зробимо так, що в початковому стані елемент (наш текст) не буде видно, надалі він з’являтиметься, коли користувач доскролить до нього.
.green {
background-color: green;
}
.red {
background-color: red;;
}
/* Задаємо висоту великим блокам, щоб у нас на сторінці вийде скролл */
.element-big {
width: 100%;
height: 1200px;
}
.element-animation {
margin: 2rem 0;
font-size: 3rem;
/* Приховуєм елемент у початковому стані */
opacity: 0;
}
Тепер перейдемо до JS – адже нам потрібно розуміти, коли користувач доскролив до потрібного елемента.
Поява контенту при скролінгу: працюємо з JS
Нам пощастило, веб не стоїть на місці і регулярно покращується, роблячи наше життя трішки простіше. Якщо раніше нам потрібно було сильно повозитися, щоб реалізувати плавну появу елементів при скролі сторінки, то тепер все стало набагато зрозумілішим.
Я не сильно заглиблюватимуся, якщо хочете, можете почитати окремо про Intersection Observer. За допомогою цього ми можемо відстежувати видимість елемента в умовному вікні користувача. І завдяки цьому ми можемо робити не тільки анімацію, а й, наприклад, відкладене завантаження, або “нескінченний” скролл.
Але повернемось до нашої теми. Вставимо в JS наступний код:
function onEntry(entry) {
entry.forEach(change => {
if (change.isIntersecting) {
change.target.classList.add('element-show');
}
});
}
let options = { threshold: [0.5] };
let observer = new IntersectionObserver(onEntry, options);
let elements = document.querySelectorAll('.element-animation');
for (let elm of elements) {
observer.observe(elm);
}
Тут ми чіпляємося за клас .element-animation і стежитимемо, чи доступний він на “екрані” чи ні. Зверніть увагу, що ви можете використовувати цей клас одразу до кількох елементів.
Отже, коли користувач доскролив до класу .element-animation, ми додаємо йому клас .element-show
Ось і все, що робить JS. Перевіряє чи видно клас і якщо так, то додає до нього ще один клас.
А тепер знаючи це, повернімося до CSS.
Поява елементів на сайті: заключний крок
У нас додається клас. Element-show до класу. Давайте зробимо його видимим. Для цього досить просто прописати в CSS наступне:
.element-animation.element-show {
opacity: 1;
transition: opacity 1s;
}
Ось і все, тепер наш блок буде видимим, коли до нього доскролить користувач.
Якщо хочете, ви можете зробити так, щоб елемент з’являвся знизу:
.element-animation {
margin: 2rem 0;
font-size: 3rem;
/* Приховуєм елемент у початковому стані */
opacity: 0;
transform: translateY(100%);
}
.element-animation.element-show {
opacity: 1;
transition: all 1s;
transform: translateY(0%);
}
Нічого складного. Ви можете експериментувати, додаючи різні варіанти до початкового стану, потім змінюючи їх на стандартні. Спробуйте, наприклад, погратись із transform: rotate(5deg).
See the Pen Появление элементов при прокрутке страницы by Pelegrin (@pelegrin2puk) on CodePen.
Видео

Дуже дякую, не знала про IntersectionObserver. Але чомусь в мене на мобільних пристроях акивний клас вже відразу додаєься до єлементів, ще до того, я я почала прокручувати. На десктопі все працює, як треба. Можете підказати, в чому може бути причина?
Так важко сказати, в чому може бути причина. Можете додати ваш код на https://jsfiddle.net/ – так буде зручніше зрозуміти.
Дякую, сама знайшла 🙂 Напишу тут, може комусь допоможе. В мене через translateX, який я використовую для анімації якимось дивовижним чином змінювалися розміри тега html, хоча інструменти розробника в хромі показували значення такі, як треба.. але сам сайт при цьому можна було зсунути вправо і з’являлася біла полоса. Коротше, тільки overflow-x: hidden для html мені допомогло
Все отлично работает, спасибо. Единственное не смог разобраться как добавлять класс к другому элементу, а не к текущему, до которого дошла прокрутка. Вместо
change.target.classList.add(‘element-show’);
добавляю другой элемент.
document.getElementById(‘myid’).classList.add(“show”);
Но естественно ничего не получается.
Нужно, чтобы при прокрутке к элементу .element-animation Добавлялся класс к элементу айди myid. Спасибо.
Не зовсім зрозуміло, що саме ви робите і що саме не працює. Можете скинути ваш код на https://jsfiddle.net/ ?
Здраствуйте! использую этот код для вызова функции. После пролистывания вниз и возвращения к обьекту код перестает адекватно срабатывать. Как правильно записать что бы после попадания в зону видимости, код продолжил работу даже после пролистывания?
Что вы имеете ввиду под “перестает адекватно срабатывать”? Есть ошибка в консоли?
Не работает скрипт
Значит вы что-то упустили. Проверьте все еще раз внимательно. Возможно не добавили нужные классы в html?
Что-то не работает ваш скрипт
работает
Добрый день! Подскажите пожалуйста, как реализовать появление, если я использую анимацию из библиотеки anime.js? Возможно ли как-то использовать функцию из библиотеки вместо CSS?
добрый день) А как сделать чтобы всплывающий элемент при скролинге до конца страницы остановился пере футером
Добрый день, спасибо за код!
Подскажите, пожалуйста, я применяю його при скролле изображений в карточке товара, скролю вниз, все плавно появляется, одно изображение за другим, очень красиво.
А можно как то сделать, чтобы пользователь если пролистал вверх и остановился на самой первой карточке, чтобы нижние пропали и отображалась только первая фотография? Изначально при загрузке страницы так и отображается только одно изображение, а если пролистать вниз и снова вверх, все фото остаются.
Надеюсь, понятно объяснила 🙂 спасибо!
Добрый вечер 🙂
Если правильно понял ваш вопрос, то попробуйте в функцию onEntry добавить условие для else:
function onEntry(entry) {
entry.forEach(change => {
if (change.isIntersecting) {
change.target.classList.add(‘element-show’);
} else {
change.target.classList.remove(‘element-show’);
}
});
}
не актуально под мобильные устройства
Почему не актуально? На каком устройстве/браузере у вас не работает? Технология имеет отличную поддержку – https://caniuse.com/?search=IntersectionObserver
Добрый день! Подскажите пожалуйста, как реализовать, чтобы после появления одного элемента таким же образом появлялся следующий? Вставляю второй элемент, а он появляется вместе с первым?
Попробуйте второму элементу задать задержу в css.
Например:
.second_element {
transition-delay: 1s;
}