Appearance of elements on scrolling
In this article, we’ll look at how you can make elements appear smoothly when the page is scrolling.
We’ll use CSS and some native JS, no third-party libraries. Buckle up!
You’ve probably seen on many websites beautiful animations where blocks appear at the moment you scroll down to them. Sometimes they appear from bottom to top, sometimes from left to right, and sometimes it’s not even clear how. Now I’ll show you how to do it.
Scrolling animation: creating html
It all starts with html. Let’s do the markup.
<div class="wrap">
<div class="element-big green"></div>
<div class="element-animation">
<span>The element that appears</span>
</div>
<div class="element-big red"></div>
</div>
Here we have created two big blocks with text between them. We need the two big blocks to make the page scroll.
Now let’s add a CSS for them and you will understand everything.
Appearance of elements on page scrolling: add initial CSS
In CSS, we first set the height of the big blocks so that we have a scroll on the page. This is only for demonstration purposes.
And secondly, let’s make the element (our text) not be visible in the initial state, but later it will appear when the user scrolls to it.
.green {
background-color: green;
}
.red {
background-color: red;;
}
/* Setting the height of the big blocks, so that we get a scroll on the page */
.element-big {
width: 100%;
height: 1200px;
}
.element-animation {
margin: 2rem 0;
font-size: 3rem;
/* Hiding the element in the initial state */
opacity: 0;
}
Now to JS – we need to understand when the user has scrolled to the needed element.
Appearance of content when scrolling: working with JS
We’re lucky that the web keeps moving forward and regularly improves, making our lives a little easier. If before we had to struggle a lot to implement a smooth appearance of elements when you scroll the page, now everything is much clearer.
I won’t go too deep, if you want, you can read about the Intersection Observer separately. With this, we can track the visibility of an element in the conditional “window” of the user. And thanks to this we can make not only animation, but also, for example, delayed loading or “infinite” scrolling.
But back to our topic. Let’s insert the following code into 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);
}
Here we catch the .element-animation class and will keep track of whether it is available on the “screen” or not. Note that you can use this class on several elements at the same time.
So, when the user has scrolled to the element with .element-animation class, we add to it the .element-show class.
That’s all JS does. It checks if the class is visible and if so, adds another class to it.
Now knowing that, let’s go back to CSS.
Appearance of elements on a website: the final step
We have the .element-show class added to the .element-animation class when the user scrolls to it. Let’s make it visible. To do this, just write the following in CSS:
.element-animation.element-show {
opacity: 1;
transition: opacity 1s;
}
That’s it, now our block will be visible when the user scrolls to it.
You can make the item appear from the bottom if you want:
.element-animation {
margin: 2rem 0;
font-size: 3rem;
/* Hiding the element in the initial state */
opacity: 0;
transform: translateY(100%);
}
.element-animation.element-show {
opacity: 1;
transition: all 1s;
transform: translateY(0%);
}
There is nothing complicated about it. You can experiment by adding different variants to the original state, and then changing them to the standard ones. Try, for example, trying different values for the transform: rotate(5deg); property.
See the Pen Appearance of elements when the page is scrolled by Pelegrin (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;
}