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

🗓️ Обновлено: 11.08.2022
💬Комментариев: 22
👁️Просмотров: 61416

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

В этой статье мы рассмотрим, как можно сделать плавное появление элементов при прокрутке страницы.

Мы будем использовать 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 к классу .element-animation, когда до него доскроллил юзер. Давайте же сделаем его видимым. Для этого достаточно просто прописать в CSS следующее:

.element-animation.element-show {
  opacity: 1;
  transition: opacity 1s;
}

Bот и все, теперь наш блок будет видимым, когда до него доскроллит пользователь.

Если хотите, вы можете сделать так, чтобы элемент появлялся снизу:

.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
Подписывайся и не пропускай:
Актуальные новости
Интересные задачки
Полезные подборки
Статья была полезной?
👍
Да - 99
👎
Нет - 26
💬Комментарии:
Александр

Добрый вечер! Подскажите пожалуйста, а если нужно, чтобы один элемент появлялся снизу, второй сверху, каким образом измениться js? С css разобрался.
Заранее спасибо!

Юрий

Чувак, спасибо тебе! То, что нужно! Челу, который знает css + html но забыл(или не хочет парить моск) самое — то! Успехов во всём!

Владимир

Спасибо большое за отличное решение.

Марина

Дуже дякую, не знала про 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
Подписывайся и не пропускай:
Актуальные новости
Интересные задачки
Полезные подборки
Наш рейтинг
🏆Лучшие биржи ссылок
4.8
2
4.0
3.8
4
GoGetLinks
3.5
5
Miralinks
3.5
Наш рейтинг
🏆Лучший хостинг для сайта
9/10
8/10
8/10
4
8/10
8/10
7/10
7/10
Проверка знаний
🤔Хорошо ли вы знаете CSS?
Есть два блочных элемента, которые идут друг за другом в html. Какой будет оступ (margin) между ними, если задать им такие стили:

.top {
  height: 30px;
  background-color: blue;
  margin-bottom: 10px;
}
.bottom {
  height: 30px;
  background-color: red;
  margin-top: 20px;
}
    
10px
20px
30px
Peach Fuzz
🤔Цвет 2024 года
Исследовательский институт Pantone выбрал главный цвет 2024 года. Им стал нежный бархатистый персиковый оттенок, получивший название Peach Fuzz (Персиковый пух).
#febe98