Skrollr – CSS animations linked to scroll position

Having seen a few single-page year in review minisites the past few weeks, it’s clear that Skrollr has become the de facto standard to implement parallax scrolling effects into your websites.

The idea behind Skrollr is straightforward: link a target CSS property+value to a given scroll position, via data-* attributes:

<div id="example" data-0="width:100%;" data-1500="width:0%;"></div>

Skrollr will interpolate between the start and end value whilst you scroll.

Note that the resulting effect is different from the previously mentioned Scroll Animations. Whereas Scroll Animations triggers an effect when an elements scroll into view (and it cannot be undone once it was started), Skrollr is tightly linked to the actual scroll position/offset: scrolling up will revert the animation.

A really neat (and CPU intensive) example is Flat Design vs. Realism.


The folks over a Pingdom have created a little helper function, which they’ve used in their year in review page, to define all values via JavaScript. The essence of the function is this (simplified version of their code):

var setSkrollr = function($el, data) {
    for (var i = 0, l = data.length; i < l; i++) { // loop all data entries (scroll positions + css property & value)
        var d = data[i], // the current data entry
            px = d[0]; // the scroll position (in pixels)
            css = d[1]; // the css property + value to set
        $el.attr('data-' + px, css);

Usage is as follows:

setSkrollr($('#example'), [[0, 'width:100%'], [1500, 'width:0%']]);
setSkrollr($('#example2'), [[0, 'transform:translateY(-100%)'], [1500, 'transform:translateY(100%)']]);

I've knocked up a quick demo on codepen:

Check out this Pen!

The key part is position: fixed on all elements to prevent them from scrolling offscreen whilst you scroll. If you don't want to do this, you could wrap all elements into one wrapper div with position: fixed applied to it:

Check out this Pen!

A nice and simple example to get some more inspiration from is this Christmas-themed page.


Skrollr →
Flat Design vs. Realism →
Pingdom: 2013 – year in review →
Merry Xmas Demo →

Related: The aforementioned Scrollorama does about the same

Did this help you out? Like what you see?
Consider donating.

I don't run ads on my blog nor do I do this for profit. A donation however would always put a smile on my face though. Thanks!

☕️ Buy me a Coffee ($3)

Published by Bramus!

Bramus is a frontend web developer from Belgium, working as a Chrome Developer Relations Engineer at Google. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Unless noted otherwise, the contents of this post are licensed under the Creative Commons Attribution 4.0 License and code samples are licensed under the MIT License

Join the Conversation


  1. Hi, I’m using this method, but the scripts added this line: , creating a space under the body of about 500px. When I remove the scripts, line and space disappear. I can not find how to solve it and do not know if you’ll have the answer.

    PS: sorry for my english (I write from Argentina).

  2. The 500px is Skrollr creating extra white space. You’ll want to set forceHeight to false when you initialize skrollr.

    forceHeight: false

  3. Hey, you guys know of any resources talking about using click events on internal links while using skrollr. Like click on a DOM element and scroll to y position or #target?

  4. the 750/1500 values in the js – I can set them to a px value but would it be possible to have them be “middle of page” and “end of page”, respectively? for blog pages, where the height of a page isn’t s fixed number?

  5. Just a typo in the variable declaration (semi-colon instead of comma)

    var d = data[i], // the current data entry
    px = d[0], // the scroll position (in pixels)
    css = d[1]; // the css property + value to set

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.