Animating content to slide into view in the same direction using CSS transitions

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>

Answer №1

I think your approach is solid, but here's another idea using CSS transitions in combination with a setTimeout() function. You can create a variable to control the click events and ensure that one transition finishes before allowing another click.

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

    //check if previous transition has completed
    if(finish == true){ 

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

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for maintaining the original value of a state variable on a child page in ReactJS. Keeping the initial value passed as props from the parent page

Whenever the 'isChildOpen' flag in the parent is true, my child page opens. The goal now is to ensure that the state variable filtered2 in the child component remains constant. While both filtered and filtered2 should initially receive the same v ...

Revise the form used to edit data stored in Vuex and accessed through computed properties

My form component is used for client registration and editing purposes. Upon creation of the form component, I check if there is an ID in the URL to determine which type of form to display. If no ID is present (indicating a new client registration), all fi ...

Launch a bootstrap modal from a different webpage

If you're looking to open multiple modals with different content displayed from HTML files, check out this example below: <div id="how-rtm-works" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" ...

Utilizing Mantine dropzone in conjunction with React Hook Form within a Javascript environment

Can Mantine dropzone be used with React hook form in JavaScript? I am currently working on a modal Upload using Tailwind components like this import { useForm } from 'react-hook-form'; import { Group, Text, useMantineTheme } from '@mantine/c ...

Is there a way to extract a list of words from a designated element using selenium?

I have been trying to scrape the content of this webpage 10 Fast Fingers in order to extract the words that need to be typed into a list. My intention is to then input these words into a text box for typing practice. The code seems to be running fine, but ...

Display the div when scrolling downwards beyond 800px

Is there a way to display a hidden section when scrolling down the page, specifically after reaching a point 800px from the top? I currently have an example code that may need some modifications to achieve this desired effect. UPDATE: [Additionally, when ...

Issue with CasperJS: The function this.waitForUrl is not defined and is causing an error

My casperJS script handles form filling, however I encountered the following error message: A TypeError occurred: 'undefined' is not a function (evaluating 'this.waitForUrl') I suspect this might be an issue with using an outdated ver ...

Efficiently update a multi-step form using Ajax and jQuery by adding new content without needing to reload the

Is it possible to create a multistep form on a single page without reloading the div with content from a PHP file, but instead appending it below? Here is my current progress: $(document).on('submit', '#reg-form', function(){ var ln = ...

Conflicting events arising between the onMouseUp and onClick functions

I have a scrollbar on my page that I want to scroll by 40px when a button is clicked. Additionally, I want the scrolling to be continuous while holding down the same button. To achieve this functionality, I implemented an onClick event for a single 40px s ...

Tips for altering the browser tab color on a PC or Mac with HTML or JavaScript

While I am aware of the method to change theme colors on mobile devices using <meta name="theme-color" content=" #0000ffbb" />, I prefer browsing on my laptop. Are there ways to customize browser tab appearance using HTML or JS fo ...

Ways to broaden the map of a variable in SCSS

Currently, I am utilizing a package known as Buefy, which acts as a Vue.js wrapper for the Bulma CSS framework library. Within Buefy's template components, there is an attribute/property called type (e.g., type="is-warning"). According to the document ...

Router Express, parsing the body, and submitting a POST request

I have been experimenting with express.Router to organize my routes and testing post requests using Postman. I noticed that when I make a post request to /test without using router body-parser, everything works fine and I can view the body content. However ...

"Creating a new element caused the inline-block display to malfunction

Can someone explain why the createElement function is not maintaining inline-block whitespace between elements? Example problem First rectangle shows normal html string concatenation: var htmlString = '<div class='inline-block'...>&l ...

The font styles shift and vertical bars vanish when placed under images

I'm currently facing some challenges with the text placement beneath the images on my website that I am constructing: 1) The font for "Back to home page" unexpectedly changes from the specified style (Georgia, 0.9em) in Firefox but remains consistent ...

Best practices for utilizing child component methods within a parent component in VUE

I am working with the ImageUpload.vue component, which is a straightforward Bootstrap modal containing a few methods. I am currently exploring the best approach to utilize one of these methods. Could it be implemented like this: const app = new Vue({ ...

The use of a <button> element in a React App within a Web Component with Shadow DOM in Chrome disables the ability to highlight text

An unusual problem has arisen, but I have a concise example that demonstrates the issue: https://codesandbox.io/s/falling-architecture-hvrsd?file=/src/index.js https://i.stack.imgur.com/CkL4g.png https://i.stack.imgur.com/nDjuD.png By utilizing the divs ...

The subsequent middleware in express next() is failing to trigger the next middleware within the .catch() block

I'm facing a puzzling issue with my POST route. It's responsible for creating transactions through Stripe using the Node package provided by Stripe. Everything works smoothly until an error occurs, such as when a card has insufficient funds. Whe ...

JavaScript | Calculating total and separate scores by moving one div onto another div

I have a fun project in progress involving HTML and Javascript. It's a virtual zoo where you can drag and drop different animals into their designated cages. As you move the animals, the total count of animals in the zoo updates automatically with the ...

Guide to integrating react-phone-number-input into material-ui TextField

Would it be possible for me to use a Material UI TextField component as the inputComponent prop for the PhoneInput component from react-phone-number-input? I am facing an issue where I am unable to apply the ref successfully. Even though I can see the Mat ...

Postman's ability to capture elements that meet specific criteria set by another element

Here is the output of my response code: [ { "id": 364, "siteName": "FX21 - PortA", }, { "id": 364, "siteName": "FX21 - PortB", }, { "id": 370, "siteName": "FX05 - ER", }, I'm tr ...