<h1>Flickity - layered parallax, jQuery</h1>

<div class="parallax">
  <!-- background parallax layer -->
  <div class="parallax__layer parallax__layer--bg">
    <div class="parallax__layer__cell parallax__layer__cell--bg"></div>
    <div class="parallax__layer__cell parallax__layer__cell--bg"></div>
    <div class="parallax__layer__cell parallax__layer__cell--bg"></div>
    <div class="parallax__layer__cell parallax__layer__cell--bg"></div>
    <div class="parallax__layer__cell parallax__layer__cell--bg"></div>
  </div>
  <!-- carousel: midground parallax layer -->
  <div class="carousel">
    <div class="carousel-cell"></div>
    <div class="carousel-cell"></div>
    <div class="carousel-cell"></div>
    <div class="carousel-cell"></div>
    <div class="carousel-cell"></div>
  </div>
  <!-- foreground parallax layer -->
  <div class="parallax__layer parallax__layer--fg">
    <div class="parallax__layer__cell parallax__layer__cell--fg"></div>
    <div class="parallax__layer__cell parallax__layer__cell--fg"></div>
    <div class="parallax__layer__cell parallax__layer__cell--fg"></div>
    <div class="parallax__layer__cell parallax__layer__cell--fg"></div>
    <div class="parallax__layer__cell parallax__layer__cell--fg"></div>
  </div>
</div>
/* external css: flickity.css */

* { box-sizing: border-box; }

body { font-family: sans-serif; }

/* parallax */

.parallax {
  position: relative;
  overflow-x: hidden;
  height: 360px;
}

.parallax__layer {
  position: absolute;
  left: 0;
  top: 0;
}

.parallax__layer--bg {
  top: 70px;
  width: 80%;
  height: 160px;
}

.parallax__layer--fg {
  pointer-events: none;
  width: 125%;
  height: 300px;
}

.parallax__layer__cell {
  position: absolute;
  width: 50%;
  margin: 0 5%;
  height: 100%;
}

.parallax__layer__cell:nth-child(1) { left: 0%; }
.parallax__layer__cell:nth-child(2) { left: 60%; }
.parallax__layer__cell:nth-child(3) { left: 120%; }
.parallax__layer__cell:nth-child(4) { left: 180%; }
.parallax__layer__cell:nth-child(5) { left: 240%; }

.parallax__layer__cell--bg {
  background: hsla(210, 100%, 50%, 0.4);
}

.parallax__layer__cell--fg {
  background: hsla(60, 100%, 50%, 0.4);
}

/* carousel */


.carousel-cell {
  height: 220px;
  width: 50%;
  margin: 40px 5%; /* total width = 50% + 5% + 5% = 60% */
  background: #8C8;
  opacity: 0.6;
  border-radius: 5px;
  counter-increment: carousel-cell;
}

/* cell number */
.carousel-cell:before {
  display: block;
  text-align: center;
  content: counter(carousel-cell);
  line-height: 200px;
  font-size: 80px;
  color: white;
}
// external js: flickity.pkgd.js

var $carousel = $('.carousel').flickity();
var $background = $('.parallax__layer--bg');
var $foreground = $('.parallax__layer--fg');

var cellRatio = 0.6; // outerWidth of cell / width of carousel
var bgRatio = 0.8; // width of background layer / width of carousel
var fgRatio = 1.25; // width of foreground layer / width of carousel

var flkty = $carousel.data('flickity');
var count = flkty.slides.length - 1;

$carousel.on( 'scroll.flickity', function( event, progress ) {
  moveParallaxLayer( $background, bgRatio, progress );
  moveParallaxLayer( $foreground, fgRatio, progress );
});
// trigger initial scroll
$carousel.flickity('reposition');

function moveParallaxLayer( $layer, layerRatio, progress ) {
  var ratio = cellRatio * layerRatio;
  $layer.css({
    left: ( 0.5 - ( 0.5 + progress * count ) * ratio ) * 100 + '%'
  });
}

External CSS

  1. https://npmcdn.com/flickity@2/dist/flickity.css

External JavaScript

  1. https://code.jquery.com/jquery-3.1.0.min.js
  2. https://npmcdn.com/flickity@2/dist/flickity.pkgd.js