John
John

Reputation: 1341

Transition Content into view from the same direction using CSS Transitions

I am attempting to slide one of two 'pages' i.e <divs> into view with a gentle transition where the user can see one page sliding out whilst the other page slides in. In my final application, the transition will be triggered from my backend (probably with a WebSocket message).

I would like the pages to slide in from the left and for the effect to 'loop'; that is that when returning to the first page, it still slides in from the left.

I have created a snippet below which demonstrates my current plan of using a CSS3 transition to achieve the desired effect. It works but feels very clunky.

It operates as follows:

#page1 starts in view and #page2 has it's horizontal position offset by its width through use of the in-frame and out-of-frame classes respectively.

For #page1 to #page2 transition, I simply apply the .slide class which uses a transform:translateX() to reposition both 'pages' by their width and the transition property of the page class handles the transition effect.

In order to perform loop-like behaviour I wait for the transition to finish, then I toggle which page has which in-frame or out-of-frame class with the intention of bringing #page1 back to being off-screen to the left of #page2. However in order to prevent this position-change running as a transition, I have to apply the .notransition class which feels like a kludgey work-around.

My Question: Is there a better way to achieve this behaviour using CSS transitions?

I know bootstrap's carousel can do it for me like this but it would be nice to know if/where I am 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>

Upvotes: 1

Views: 320

Answers (1)

DesignMonkeyJim
DesignMonkeyJim

Reputation: 1935

Your way looks good to me, another solution still using CSS transitions could be to use a setTimeout() and create a variable which you check to see if it has changed before allowing another click.

//set a variable
var finish = true;
$('body').click(function() {

    //check to see if last transition has finished
    if(finish == true){ 

      //set variable to false
      finish = false;
        // start transform
        $('.page').removeClass('notransition').addClass('slide');

        setTimeout(function(){ 
             finish = true;
             $('.page').toggleClass('in-frame').toggleClass('out-of-frame').addClass('notransition').removeClass('slide')
              }
        ,2000);
    }
});

Upvotes: 1

Related Questions