Basic scrolling example.

by razh

HTML

<div class="container"></div>
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>
<div class="container"></div>
<div class="box"></div>
<div class="box fast"></div>
<div class="box fast easing"></div>
<div class="scrollTop">0px</div>

CSS

body {
    margin: 0;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 1.5em;
    color: #fff;
}

.box {
    position: fixed;
    top: calc(50% - 100px);
    
    margin-top: -25px;
    width: 50px;
    height: 50px;

    background-color: #fff;
}

.fast {
    top: 50%;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
}

.easing {
    top: calc(50% + 100px);
    -webkit-transition: all 0.1s;
    transition: all 0.1s;
}

.container {
    width: 100%;
    height: 960px;
}

.container:nth-child(1) { background-color: #96CEB4; }
.container:nth-child(2) { background-color: #FFEEAD; }
.container:nth-child(3) { background-color: #FF6F69; }
.container:nth-child(4) { background-color: #FFCC5C; }
.container:nth-child(5) { background-color: #AAD880; }

.scrollTop {
    position: fixed;
    top: 1em;
    right: 1em;
    text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.2);
}

JavaScript

// Element to demonstrate scroll effect.
var boxElement = document.querySelector('.box');

// Element to demonstrate faster hardware-accelerated effect (CSS transforms).
var boxElementFast = document.querySelector('.fast');

// Element to demonstrate easing function (CSS transitions).
var boxElementEasing = document.querySelector('.easing');

// Element to display the amount we've scrolled.
var scrollTopElement = document.querySelector('.scrollTop');

window.addEventListener('scroll', function() {
    var viewportWidth = document.documentElement.clientWidth;
    var viewportHeight = document.documentElement.clientHeight;
    
    // The current page scroll position.
    var scrollY = document.body.scrollTop;
    // The total scrollable height of the page.
    var scrollHeight = document.body.scrollHeight - viewportHeight;

    var scrollRatio = scrollY / scrollHeight;
    
    // getComputedStyle() allows us to access the applied CSS styles of the element.
    // Here, we get the width so that the box does not go off the screen.
    var boxWidth = parseFloat(getComputedStyle(boxElement).width);
    
    // Translation along the x-axis.
    var x = scrollRatio * (viewportWidth - boxWidth);
    boxElement.style.left = x + 'px';

    // By translating in 3d instead of adjusting the 'left' CSS property,
    // we "promote" this box element to a GPU-accelerated layer.
    // That is, it isn't redrawn every time it moves.
    // This results in a noticeably smoother scroll effect, especially with more complex animations.
    var transform = 'translate3d(' + x + 'px, 0, 0)';
    boxElementFast.style.webkitTransform = transform;
    boxElementFast.style.transform = transform;

    // Set the transform for the element with easing applied.
    boxElementEasing.style.webkitTransform = transform;
    boxElementEasing.style.transform = transform;
    
    // Display the total number of pixels scrolled.
    scrollTopElement.innerHTML = scrollY + 'px';
});