JSFiddle - React, Tailwind, and code Playground

by BurpmanJunior

HTML

<div id="scroller">
  <div>
    <div class="left">
      <div style="background-color: #fff;"><div>Left content #1</div></div>
    </div>
    <div class="right">
      <div style="background-color: #eee;"><div>Right content #1</div></div>
    </div>
  </div>
  <div>
    <div class="left">
      <div style="background-color: #eee;"><div>Left content #2</div></div>
    </div>
    <div class="right">
      <div style="background-color: #fff;"><div>Right content #2</div></div>
    </div>
  </div>
  <div>
    <div class="left">
      <div style="background-color: #fff;"><div>Left content #3</div></div>
    </div>
    <div class="right">
      <div style="background-color: #eee;"><div>Right content #3</div></div>
    </div>
  </div>
</div>
<div class="lower-content">
  <p>Etiam feugiat lorem non metus. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Aliquam eu nunc. Praesent blandit laoreet nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
  <p>Phasellus volutpat, metus eget egestas mollis, lacus lacus blandit dui, id egestas quam mauris ut lacus. Cras ultricies mi eu turpis hendrerit fringilla. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. Suspendisse nisl elit, rhoncus eget, elementum ac, condimentum eget, diam. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
  <p>In ac felis quis tortor malesuada pretium. Phasellus nec sem in justo pellentesque facilisis. Praesent egestas neque eu enim. Praesent nonummy mi in odio. Nullam quis ante.</p>
</div>

CSS

html, body {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
}

* {
  box-sizing: border-box;
}

#scroller {
  display: block;
  width: 100%;
  position: relative;
  margin: 0;
  padding: 0;
  opacity: 0;
  transition: opacity 1000ms ease-in-out;
  -webkit-transition: opacity 1000ms ease-in-out;
  -moz-transition: opacity 1000ms ease-in-out;
  -ms-transition: opacity 1000ms ease-in-out;
  -o-transition: opacity 1000ms ease-in-out;
}
#scroller.scroller-init {
  opacity: 1;
}

@media screen and (min-width: 1024px) {

  #scroller > .responsive-content {
    display: none;
  }

  #scroller {
    height: 100vh;
    overflow: hidden;
  }
  #scroller.scroller-init > div.left-render,
  #scroller.scroller-init > div.right-render {
    transition: top 1000ms ease-in-out;
    -webkit-transition: top 1000ms ease-in-out;
    -moz-transition: top 1000ms ease-in-out;
    -ms-transition: top 1000ms ease-in-out;
    -o-transition: top 1000ms ease-in-out;
    position: absolute;
    width: 50%;
  }

  #scroller.scroller-init > div.left-render > div,
  #scroller.scroller-init > div.right-render > div {
    overflow: hidden;
    height: 100vh;
    padding: 20px;
    top: 0;
  }
  #scroller > div.left-render {
    left: 0;
  }
  #scroller > div.right-render {
    right: 0;
  }
  #scroller > div > div > div{
    transition: opacity 300ms ease-in-out;
    -webkit-transition: opacity 300ms ease-in-out;
    -moz-transition: opacity 300ms ease-in-out;
    -ms-transition: opacity 300ms ease-in-out;
    -o-transition: opacity 300ms ease-in-out;
    opacity: 0.3;
  }
  #scroller > div > div.current-slide > div{
    opacity: 1;
  }

}

@media screen and (max-width: 1024px) {

  #scroller > div.left-render,
  #scroller > div.right-render {
    display: none;
  }

  #scroller > .responsive-content {
    display: block;
  }
  #scroller > .responsive-content > div > div{
    padding: 20px;
    min-height: 200px;
    max-width: calc(100% - 40px);
    margin: 20px auto;
    box-shadow: 0 1px...

JavaScript

var scroller = {
  wrapper: $('#scroller'),  // Main container
  minimumWidth: 1024,        // Breakpoint to disable on
  animationDuration: 1000,  // Animation duration. Match CSS transitions for best results

  /**
   * Stored variables for processing
   */
  processing: false,
  locked: true,
  slides: {
    totalCount: 1,
    currentSlide: 1
  },

  /**
   * Initialize scroller
   */
  init: function () {
    // Count slides
    scroller.slides.totalCount = scroller.wrapper.children().length;
    // Run setup functions
    scroller.lock();
    scroller.bindEvents();
    scroller.buildDOM();
  },

  /**
   * Rearranges elements into proper layout and calculates initial positions
   */
  buildDOM: function () {
    // Position calculations
    var leftShift = (100 * (scroller.slides.totalCount - 1));
    var rightShift = (100 * (scroller.slides.currentSlide - 1));

    // Left & right element setup
    var leftElem = $('<div />').addClass('left-render').css('top', '-' + leftShift + 'vh');
    var rightElem = $('<div />').addClass('right-render').css('top', rightShift + 'vh');
    // Mobile and table element
    var originalElem = $('<div />').addClass('responsive-content');

    // HTML extraction and sorting
    scroller.wrapper.children().each(function () {
      leftElem.prepend($('.left', this).html());
      rightElem.append($('.right', this).html());
      originalElem.append($(this).html());
      $(this).remove(); // Remove old element when sorted
    });

    // Build DOM and add initialize class
    scroller.wrapper.append(originalElem).append(leftElem).append(rightElem).addClass('scroller-init');
    scroller.updateSlides();
  },

  /**
   * Updates slide position offsets and current slide classes
   */
  updateSlides: function () {
    // Update render section position offsets
    $('.left-render', scroller.wrapper).css('top', '-' + (100 * (scroller.slides.totalCount - (scroller.slides.currentSlide))) + 'vh');
    $('.right-render',...