Поява елементів при скролі

🗓️ Оновлено: 11.08.2022
💬Коментарів: 19
👁️Переглядів: 33719

У цій статті ми розглянемо, як можна зробити плавну появу елементів під час прокручування сторінки.

Ми будемо використовувати 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.

Видео

CSS Головоломки в Telegram
Підписуйся і не пропускай:
Актуальні новини
Цікаві завдання
Корисні добірки
Стаття була корисною?
👍
Так - 69
👎
Ні - 18
💬Коментарі:
Марина

Дуже дякую, не знала про 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’);
}
});
}

SERGEY

не актуально под мобильные устройства

Владимир

Почему не актуально? На каком устройстве/браузере у вас не работает? Технология имеет отличную поддержку – https://caniuse.com/?search=IntersectionObserver

Ольга

Добрый день! Подскажите пожалуйста, как реализовать, чтобы после появления одного элемента таким же образом появлялся следующий? Вставляю второй элемент, а он появляется вместе с первым?

Владимир

Попробуйте второму элементу задать задержу в css.

Например:

.second_element {
transition-delay: 1s;
}

CSS Головоломки в Telegram
Підписуйся і не пропускай:
Актуальні новини
Цікаві завдання
Корисні добірки
Наш рейтинг
🏆Найкращий хостинг для сайту
9/10
8/10
8/10
4
8/10
8/10
7/10
7/10
Что читают?
🏆Популярные записи
Як зробити гамбургер (бургер) меню – готовий код та докладне пояснення
Переглядів: 43501
Поява елементів при скролі
Переглядів: 33719
Як зробити плавне збільшення картинки при наведенні – ефект на чистому CSS
Переглядів: 30117
Як вирівняти картинку по центру за допомогою CSS
Переглядів: 22105
Як змінити колір SVG у CSS
Переглядів: 20365
Перевірка знань
🤔Чи добре ви знаєте CSS?
Есть два блочных элемента, которые идут друг за другом в html. Какой будет оступ (margin) между ними, если задать им такие стили:

.top {
  height: 30px;
  background-color: blue;
  margin-bottom: 10px;
}
.bottom {
  height: 30px;
  background-color: red;
  margin-top: 20px;
}
    
10px
20px
30px
Viva Magenta
🤔Колір 2023 року
Дослідницький інститут Pantone обрав головний колір 2023 року. Ним став карміново-червоний відтінок із фіолетовим підтоном, який назвали Viva Magenta.
#bb2649