My goal is to smoothly slide one of two 'pages', represented as <divs>
, into view with a gentle transition that allows the user to see one page sliding out while the other slides in. Eventually, this transition will be triggered from the backend, most likely via a WebSocket message.
I want the pages to slide in from the left and for the effect to continue in a loop; meaning when returning to the first page, it should still slide in from the left.
To achieve this, I have created a snippet below showcasing my current plan which involves using a CSS3 transition. However, I find the implementation to be somewhat clunky.
The process works as follows:
#page1
starts in view, while #page2
's horizontal position is offset by its width through the use of the in-frame
and out-of-frame
classes respectively.
For the transition from #page1
to #page2
, I simply apply the .slide
class which uses transform:translateX()
to reposition both 'pages' by their width, and the transition property of the page
class handles the transition effect.
In order to create a loop-like behavior, I wait for the transition to finish and then toggle which page has the in-frame
or out-of-frame
class to bring #page1
back off-screen to the left of #page2
. However, to prevent this position change from running as a transition, I have to use the .notransition
class, which feels like a workaround.
My Question: Is there an improved way to achieve this behavior using CSS transitions?
I am aware that Bootstrap's carousel can accomplish this for me as shown here, but I would like to know if and where I might be going wrong.
// add transition finished handler to each page
$('.page').on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function() {
// toggle in/out of frame
$(this).toggleClass('in-frame')
.toggleClass('out-of-frame')
.addClass('notransition')
.removeClass('slide')
})
$('body').click(function() {
// start transform
$('.page').removeClass('notransition').addClass('slide')
})
html,
body {
height: 100%;
overflow: hidden;
text-align: center;
font-size: 2em;
}
#content {
position: relative;
height: 100%;
}
.page {
position: absolute;
top: 0;
height: 100%;
width: 100%;
-webkit-transition: transform 2s cubic-bezier(0.19, 1, 0.22, 1);
-moz-transition: transform 2s cubic-bezier(0.19, 1, 0.22, 1);
-o-transition: transform 2s cubic-bezier(0.19, 1, 0.22, 1);
transition: transform 2s cubic-bezier(0.19, 1, 0.22, 1);
}
.slide {
-webkit-transform: translateX(100%);
-moz-transform: translateX(100%);
-o-transform: translateX(100%);
transform: translateX(100%);
}
.in-frame {
left: 0%;
}
.out-of-frame {
left: -100%;
}
.notransition {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: none !important;
transition: none !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="content">
<div id="page1" class="page in-frame" style="background: #d67e56;">
Main Page <br> (Click Me)
</div>
<div id="page2" class="page out-of-frame" style="background: #d94e4e;">
Other Page <br> (Click Me)
</div>
</div>