VueJS effects when elements are added and removed

I'm currently diving into VueJS and struggling to tackle this issue with transitions. My project includes two components - ComponentA and ComponentB. Let's take a closer look at them:

ComponentA:

<template>
<div id="ComponentA">
    <h1 class="header" v-on:click="update">HEADER</h1>
    <transition
        name="custom-classes-transition"
        enter-active-class="animated fadeInDown"
        leave-active-class="animated fadeOutUp"
    ><p class="content" v-if="visible">
        Some information...
    </p></transition>
</div>
</template>

<script>
import App from "@/App";

export default {
    datas: {
        visible: false
    },
    name: "ComponentA",
    data () {
        return this.$options.datas;
    },
    methods: {
        update () {
            App.update(this.$options.name);
        }
    }
};
</script>

<style scoped>
</style>

ComponentB:

<template>
<div id="ComponentB">
    <h1 class="header" v-on:click="update">HEADER2</h1>
    <transition
        name="custom-classes-transition"
        enter-active-class="animated fadeInDown"
        leave-active-class="animated fadeOutUp"
    ><p class="content" v-if="visible">
        Some more information...
    </p></transition>
</div>
</template>

<script>
import App from "@/App";

export default {
    datas: {
        visible: false
    },
    name: "ComponentB",
    data () {
        return this.$options.datas;
    },
    methods: {
        update () {
            App.update(this.$options.name);
        }
    }
};
</script>

<style scoped>
</style>

In my App.vue file:

<template>
  <div id="app">
      <header href="https://cdn.jsdelivr.net/npm/animate.css" rel="stylesheet" type="text/css">
      <ComponentA />
      <ComponentB />
  </div>
</template>

<script>
import ComponentA from "@/components/ComponentA";
import ComponentB from "@/components/ComponentB";

export default {
    name: "App",
    components: {
        ComponentA,
        ComponentB
    },
    update (clickedComponent) {
        for (let component in this.components) {
            component = this.components[component];

            if (component.name === clickedComponent) {
                component.datas.visible = !component.datas.visible;
            } else {
                component.datas.visible = false;
            }
        }
    }
};
</script>

<style>
@import url('https://fonts.googleapis.com/css?family=Space+Mono');

:root {
    --background: #0f0f0f;
    --blueish: #546a76;
    --grayish: #7c7c7c;
    --lighterblueish: #737c81;
}

body {
    line-height: 1.7;

    background-color: var(--background);
    color: var(--grayish);

    font-family: 'Space Mono', monospace;
    font-size: 18px;
    position: relative;

    height: 100%;
    width: 60%;
    margin: auto;
    padding-top: 10vh;
}

.header {
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;

    color: var(--blueish);
    width: max-content;
    position: sticky;
    left: 100%;
}

.header span {
    background-color: var(--lighterblueish);
    color: var(--background);
}

.content {
    padding-top: 5%;
}

.content span {
    color: var(--blueish);
}
</style>

The problem arises when I click on the header of ComponentA - its content fades in beautifully with an animation, but ComponentB abruptly moves down without any transition effects. Despite trying keys and various other strategies, I couldn't succeed in adding a smooth transition to ComponentB's movement. Any advice or solutions would be greatly appreciated!

Edit: Check out the JSFiddle here for reference: https://jsfiddle.net/44ctt020/2/

Answer №1

It appears that you are utilizing animate.css to create animations. When examining the source code, the animation fadeInDown is created using keyframes with the following properties:

0% {
  opacity: 0;
  transform: translate3d(0,-100%,0);
}
100% {
  opacity: 1;
  transform: none;
}

The use of translate3d allows the element's content to move independently without affecting its reserved space on the page. You can observe this behavior in the following codepen example: https://codepen.io/anon/pen/WMJjMO.

When component A is shown, it immediately occupies its necessary space on the page, causing component B to be pushed down before animating its content.

To achieve the desired effect, you will need to animate the height of your content element. This will cause the other component to move up or down accordingly.

I suggest referring to the Vue guide and creating a custom transition for the CSS properties of opacity and height: https://v2.vuejs.org/v2/guide/transitions.html

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 most effective strategy for managing dependencies for npm packages?

I am currently working on extracting a few Vue.js components from the main application and converting them into an npm package stored in a repository. This package will be imported and utilized across two different websites. To bundle everything, I am util ...

Pass data from a child controller to its parent using $emit

My goal is to pass values from dropdown lists and input fields in the FirstController to the MainController, and values from datepickers in the SecondController to the MainController. I have been attempting to use $emit and $on but without success. It&apos ...

Deleting uploaded images in Cloudinary for Next.js is not allowed

After successfully implementing image uploads in cloudinary for Next.js, I encountered an issue with image deletion. Despite creating the necessary routes and components, the deletion functionality is not working as expected. I am unsure of what could be ...

The unexpected behavior in React's reconciliation process: What is causing the state to remain unchanged?

While exploring the React documentation, I came across an interesting example of resetting state: here To better understand it, I created different sandboxes to experiment with. However, I am struggling to reconcile what I observe in each of them. Each s ...

How to override the styling of a parent element in CSS

I'm encountering an issue with my website's sidebar. I've set the background color to yellow for elements with the currentPage class. This works fine for the 'Home' tab, but when I try to do the same for a nested tab like 'tag ...

Animating distance with the power of animate.css

I have implemented animate.css for a login form, but it is not behaving as desired. Currently, I am utilizing the fadeInDown animation, however, it is fading in from a greater distance than intended. I would prefer it to fade in from just around 20px below ...

Using a .vue file in an HTML document: A step-by-step guide

After creating a hello.vue file, I am unsure how to actually use it in an HTML file. I have already set up webpack, <template> <p>Hello</p> <p>{{message}}</p> </template> <script> module.exports = { data: ...

Idle Time in Nextjs - Making the Most of D

I've been experiencing a significant delay of around 6 seconds when refreshing my Next.js platform. As part of my debugging process to identify the root cause of this issue, I uncovered that approximately 5 seconds of this time is classified as idle. ...

Achieving asynchronous results in the parent function with TypeScript: a guide

The code structure provided is as follows: import {socket} from './socket'; class A{ Execute(...args[]){ //logic with Promises SomeAsyncMethod1().then(fulfilled1); function fulfilled1(){ SomeAsyncMethod2(args).then(fulfilled2); ...

Encountered a Uncaught TypeError: Attempted to clear a canvas when the property 'getContext' is undefined or null

After researching multiple error solutions, none seemed to work for me. It became frustrating, leading me to consider spamming just to bypass the word limit and share my own findings with others facing similar issues. Check out the Answers section below to ...

How can I take photos in bulk when I open the camera on Ionic 3?

Is there a way to capture multiple images at once using the camera? Currently, I am only able to capture one image when the user clicks. However, I would like to capture four images when the user clicks the success button. let options: CaptureImageOption ...

Utilizing Node.js (Express) to import a JSON file from StackExchange and display the data

I've been working on a task to retrieve a json file from the stackexchange api and store it on the client side once the server loads, allowing me to make local changes to it. Despite my efforts, the page just continues loading without any results. He ...

Angular: Retrieving the Time Format from the Browser

Is there a way to retrieve the time format from the operating system or browser within Angular in order to display time in the user's preferred format? I have attempted to search for a solution, but have come up empty-handed. Thank you in advance! ...

having trouble retrieving information from the input field

I'm having trouble retrieving the user's input from the input field, can someone assist me with this issue? I can't seem to identify what the problem is here. var ftemp = document.getElementById("Farenheit").value; <td> <i ...

employing async/await in the function of a backend API

I'm facing an issue with the following code snippet: service.js module.exports = { getUser }; async function getUser({ data }) { return new Promise((resolve, reject) => { const id = data["id"]; const doc = await db.colle ...

What is the best way to display data stored in local storage using React and Typescript?

Is there a way for the data to be displayed on the browser below the save button when I click save? My setup involves using React with a TypeScript template. function ButtonDefaultExample(props: IButtonExampleProps) { const { disabled, checked } = pro ...

Load next.js images before the page finishes loading

Despite the conventional wisdom against it, I am exploring ways to preload a group of images before a page transition or prior to rendering my page. My specific scenario involves the need to display many large image files simultaneously and animate them on ...

Arrange containers into a tower?

Currently, I am exploring the concept of stacking boxes. While I have a solid grasp on how to stack them vertically from top to bottom, I find myself puzzled about how to stack them horizontally. Check out my vertical stacking method here See how I a ...

Fill various dropdowns with a list or array of values discreetly without displaying the populated values on the visible interface

I have an array with values 1,2,3,4. Using an add function, I am able to create multiple dropdowns. By default, the first dropdown always has a value of one when initially set up. When we press add and populate the second dropdown with values 2,3,4, tho ...

Enhance your web design with the mesmerizing jQuery UI drop effect combined

I'm attempting to create an animated toggle effect on a box using jQuery UI's drop feature. However, I've encountered some trouble due to the box having box-sizing: border-box applied which is causing issues with the animation. During the a ...