Go to main content

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

Simple scroll parallax

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 the data-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>
[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)';

Check Codepen for a working example

Further reading

all posts
  • Kentico Xperience

    Social media share urls enhanced by Kentico macros

    Requirements of nearly every website ask us to incorporate links for sharing content on social media. There are tools out there which generates these links for us. But wh…

  • Kentico Xperience

    Sync form submissions with Integration bus in Kentico Xperience

    In this post, I will provide you with a code snippet and tips on how to synchronize new form submissions with an external system through its REST API using the Integration bus in K…

  • Front-end & JavaScript

    Table of contents in Javascript

    In this post, I will provide you with a javascript code sample that transforms headings in a page into a structured table of contents with anchor links.