- 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 Freelance Web Developer with Kentico Expertise. He specializes in building and maintaining websites in Xperience by Kentico. Milan writes articles based on his project experiences to assist both his future self and other developers.
Find out more