Issues with Vue enter transitions not functioning as expected

I am currently involved in a project where I need to implement enter and exit animations for some components. When a component enters the screen, it should come from the bottom, and when it leaves, it should go upwards. The intended functionality is that when I change the :is property of the component tag, the current component moves upwards while the next one comes from the bottom. Here is a snippet of the code:

<template>
  <div class="home">
    <transition name="section">
      <component :is="activeSection"></component>
    </transition>
  </div>
</template>

<script>
import comp1 from './comp1';
import comp2 from './comp2';

export default {
  components: {
    comp1,
    comp2
  },
  data() {
    activeSection: 'comp1'
  }
</script>

<style scoped>
  .section-enter {
    top: 100vh;
  }
  .section-enter-to {
    top: 0vh;
  }
  .section-enter-active {
    animation-name: 'slideIn';
    animation-duration: 1s;
  }
  .section-leave {
    top: 0vh;
  }
  .section-leave-active {
    animation-name: 'slideOut';
    animation-duration: 1s;
  }
  .section-leave-to {
    top: -100vh;
  }


  @keyframes slideIn {
    from {
      top: 100vh;
    }
    to {
      top: 0
    }
  }

  @keyframes slideOut {
    from {
      top: 0vh;
    }
    to {
      top: -100vh;
    }
  }
</style>

However, the issue I'm facing is that the first component slides upwards, but the second one appears immediately without any animation.

If I render one component at a time (rather than replacing one with another using the same action), everything works perfectly fine. I am perplexed about what might be causing this inconsistency in behavior.

Answer №1

Your CSS has a few issues that need to be addressed.

Explaining CSS Transitions and Animations

It's important to understand the distinction between CSS Transitions and CSS Animations. Your current implementation mixes these concepts incorrectly, causing problems in your code.

The keyframes for the `slideIn` animation along with the `.section-enter` and `.section-enter-to` rules essentially perform the same function of transitioning the `.section` into view. However, without a transition rule specifying a time duration, the change happens instantaneously rather than animating smoothly. This same issue applies to the `slideOut` keyframes and `leave` rules as well.

.section-enter {
  top: 100vh;
}
.section-enter-to {
  top: 0;
}
.section-enter-active {
  transition: .5s; /* Make sure this rule is included */
}

.section-leave {
  top: 0;
}
.section-leave-to {
  top: -100vh;
}
.section-leave-active {
  transition: .5s; /* Ensure this rule is present */
}

To fix the problem, remove the keyframes and add the missing rules mentioned above to enable a functional CSS Transition.

Check out demo 1

Utilizing CSS Animations

An alternative approach involves using keyframes in conjunction with CSS Animations, where animations are applied via the `*-active` rules only without the need for `*-enter` / `*-leave` rules. Note that unnecessary quotes within the `animation-name: 'slideIn';` statement in your question would lead to invalid syntax and no animation taking place. Simplify it by using the shorthand `animation: slideIn 1s;` as shown below.

.section-enter-active {
  animation: slideIn 1s;
}
.section-leave-active {
  animation: slideOut 1s;
}

@keyframes slideIn {
  from {
    top: 100vh;
  }
  to {
    top: 0;
  }
}
@keyframes slideOut {
  from {
    top: 0;
  }
  to {
    top: -100vh;
  }
}

View demo 2 here

Tips on Optimizing CSS Transitions

For better animation performance, consider modifying your approach by utilizing translateY instead of transitioning the `top` property. This can lead to improved efficiency in your animations.

/* Assuming initial value of 'top' in .wrapper is 0 */

.section-leave-active,
.section-enter-active {
  transition: .5s;
}
.section-enter {
  transform: translateY(100%);
}
.section-leave-to {
  transform: translateY(-100%);
}

Explore demo 3 for reference

Answer №2

Implement a Mixin for Animation

A big thank you to @tony19 for the insightful explanation.
To simplify the process of repeating logic, it is recommended to utilize a mixin.
Additionally, the functionality of slideIn and slideOut can be consolidated by employing the reverse method:

@mixin animationmixin($type:'animation', $style:'', $duration:1s) {
    
    @keyframes #{$type}-#{$style} { // define animation
        0% { opacity: 1;  transform: none; } // reset style
        100% { @content; } // custom style
    }
    
    .#{$style} { // append '.section'
        &-enter-active, &-leave-active { // include '.section-enter-active', ...
            transition: #{$duration};
        }
        &-enter, &-leave-to {
            animation: #{$type}-#{$style} #{$duration}; // apply animation
        }
        &-leave, &-enter-to {
            animation: #{$type}-#{$style} #{$duration} reverse; // use reverse animation 
        }
    }
}

To implement, follow these steps:

@include animationmixin($style:'section') { // specify custom styling
    transform: translateY(100%);
};

Or try this approach:

@include animationmixin($style:'fade') {
    opacity: 0;
    transform: scale(0.9);
};

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

What is the process for showcasing specific data using Vue.js?

{ "status": "ok", "source": "n", "sortBy": "top", "articles": [ { "author": "Bradford ", "title": "friends.", "url": "http: //", "urlToImage": "http://" }, { ...

Tips for securely storing visitor-entered form data on our computer from our webpage

Is there a way to store the information filled out by visitors on our website? <ul class="form"> <li class="short"> <label>First Name<span class="required"></span></ ...

Understanding the usage of jQuery transitionend to prevent interruptions in CSS animations

I found a similar thread on StackOverflow but I'm struggling to apply it in my current scenario. The Setup (Welcome Ideas) I've developed a jQuery slider that will have multiple instances on one page, each containing an unknown number of childr ...

Tips for optimizing Slider Code to showcase an expanded selection of slides

I am currently troubleshooting a slider code on my ASP.NET website. After examining the HTML, JS, and CSS from the page theme, I noticed that only two slides are being displayed. However, when attempting to add a new slider HTML and adjusting the CSS for t ...

Action type is not recognized: modification

After browsing through multiple forums, I haven't found a solution that works for my particular issue with my VueJS app. The problem arises when I try to input something in my first component. Below is the code snippet: main.js import Vue from &apos ...

ReactJs - Organize your data with the sort method

In my React application, I have a table that fetches its data from an API. I need to implement sorting for one of the columns. The values in this column are usually strings of numbers but sometimes can be equal to "-" (Dash). Below is the sort function I ...

Compiling Typescript with module imports

In my project, I am working with two files named a.ts and b.ts. The interesting part is that file b exports something for file a to use. While the TypeScript compiler handles this setup perfectly, it fails to generate valid output for a browser environment ...

Learning how to utilize localStorage in conjunction with a color picker to modify the --var of :root

After spending an entire afternoon on my JavaScript issue as a beginner, I have a specific goal in mind: allowing the user to select and change the main color of the page. To implement this, I inserted a color picker in my HTML: <input type="color ...

Performing an AJAX request to the database when a change occurs, prior to submitting the

In my user setup/create form, I am including a field for the users' license/certification number which needs to be validated and returned to a specific DIV Onchange before the form is submitted. I have heard that using AJAX POST is the way to achieve ...

Is there a way to pre-load the data prior to the component rendering in ReactJS?

The main goal of my project is to retrieve data from the Google Analytics API and display it as a list. Although I am able to successfully fetch the data from the API, I am encountering an issue when passing it to another component. While I can view the da ...

Tips for showing the value in the subsequent stage of a multi-step form

Assistance is required for the query below: Is there a way to display the input field value from one step to the next in multistep forms? Similar to how Microsoft login shows the email in the next step as depicted in the image below: ...

Which method is better for HTML5/JavaScript GeoLocation: Passing data to a callback function or suspending an async call using promises?

Trying to figure out how to utilize HTML5/Javascript Geolocations effectively for passing location data to an ajax call and storing it in a database. The main challenges I'm facing are the asynchronous nature of the Geolocation call and issues with va ...

NodeJS refuses to import a file that is not compatible with its structure

My website has two important files: firebase.js gridsome-server.js The firebase.js file contains JavaScript code related to Firebase integration: import firebase from 'firebase/app' import 'firebase/firestore' const config = { ap ...

Looking to scan through a directory of .html files in Node.js to find specific element attributes?

Imagine trying to tackle this task - it's like reaching for a needle in a haystack. Picture a folder containing a static website, complete with images, stylesheets, and HTML files. My Node application needs to dive into this folder and extract only th ...

Hovering over a Raphael animation - What's preventing it from functioning?

I'm currently working on a pie chart using Raphael, and I want to add a tooltip that displays text when hovering over a specific segment of the chart. The hover event is functioning correctly, but I'm having trouble adjusting the tooltip text coo ...

Utilizing the CSS Top and Left attributes along with Jquery animations

There are two divisions on a page, namely Left_Div and Right_Div. The images in the Right_Div are positioned using CSS properties such as Top and Left. The Left_Div acts as a left panel, and upon clicking a button, both Left_Div and Right_Div animate to sl ...

Finding the identification of the first element within a nested div using JQuery

Here is the HTML snippet that I am working with: <div id="parent"> <div id="computer"> <div id="items"> <div id="1">hp</div> <div id="2">compaq</div> <div id="3"& ...

Navigate within a single component on the Stack by scrolling

I'm a huge fan of CSS! Although it may seem like a simple task, I am completely stumped on how to tackle it. Mission: My goal is to enable scrolling only within the List section without affecting the entire page. Here's the structure of my ...

Learn how to easily alter the background color of a div in real-time by utilizing a color picker or color swatches feature in your

Would it be feasible to dynamically alter the background color of the .hasPicked class? I am interested in adjusting the background color using an input color picker and color swatches. I have already included the necessary code on Codepen. Check it out h ...

"Need guidance with jQuery and CSS layout alignment on the

So here's the scenario I'm dealing with: <div id="tabs"> <div id="tab_one"> Content for tab one </div> <div id="tab_two"> Content for tab two </div> <div id="tab_three"> ...