- Web development
Simple scroll parallax
Recently, a designer asked me to add a parallax background image on a website. I researched the web to find a suitable solution. Regrettably, I found only massive libraries that would do the thing but bring in a lot of unnecessary javascript code. That is no go for me. I wanted a lightweight and straightforward solution. It took me a while, but I came up with the following code that works perfectly for my needs and hopefully will serve you well too. Check Codepen for a working example.
The first thing we need is HTML and CSS
- DIV with the
data-parallax
attribute is a container that holds the parallax image and content - DIV with the
data-parallax-target
attribute stands for the parallax image. It is positioned absolutely to the parent element and moves as a user scrolls thanks to javascript code (explained below). The key here is that thedata-parallax-target
element has the bottom property set to be higher than its parent element. - DIV with the content class name is positioned relatively and contains everything that we want to render on top of the parallax image.
<div data-parallax="hey">
<div data-parallax-target="hey"></div>
<div class="content">
<h1>Hello world</h1>
</div>
</div>
[data-parallax] {
position: relative;
overflow: hidden;
}
[data-parallax-target] {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: -200px;
background-image: url('https://www.milanlund.com/img/splash/about-me--480.jpg');
background-size: cover;
background-position: center center;
transform: translate3d(0, 0, 0);
transition: transform .1s linear;
}
h1 {
padding: 3em 1em;
}
.content {
position: relative;
}
And of course a bit of javascript code
On the scroll event, the code checks whether the data-parallax
element is in the viewport. If positive, the translate position gets computed for the data-parallax-target
so that the image moves. For better performance, you can use a passive event listener for the scroll event.
(function () {
var parallax = document.querySelectorAll('[data-parallax]');
window.addEventListener('scroll', function () {
for (var i = 0; i < parallax.length; i++) {
var parallaxTarget = document.querySelector('[data-parallax-target="' + parallax[i].getAttribute('data-parallax') + '"]');
var viewportOffset = parallax[i].getBoundingClientRect();
var visibilityIndex = viewportOffset.top / window.innerHeight * 100;
if (visibilityIndex >= 0 && visibilityIndex <= 100) {
var parallaxOffset = parseInt(getComputedStyle(parallaxTarget).bottom);
parallaxTarget.style.transform = 'translate3d(0, ' + Math.floor(parallaxOffset - (visibilityIndex / 100 * parallaxOffset)) + 'px, 0)';
}
}
});
})();
About the author
Milan Lund is a Full-Stack Web Developer, Solution Architect, and Consultant for Xperience by Kentico projects, working as both a freelancer and a contractor. He specializes in building and maintaining websites using Xperience by Kentico. Milan writes articles based on his project experiences to assist both his future self and other developers.
Find out more