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',...