Creating CSS animation for the most recent element that has been dynamically inserted using JavaScript and Vue.js

After adding a new div with Vue, I noticed that the opacity effect is being applied to the previous element instead of the newly added one. I want the effect to always appear on the latest element added at index 0. What could be causing this issue?

Here is the HTML code:

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Preguntas en vivo</title>
    <link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dfbdb0b0abacabadbeaf9feaf1eff1ed">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <link rel="stylesheet" href="css/style.css">

</head>
<body>

    <div id="app">
        <div class="mt-5 d-flex flex-column align-items-center container">
            <div>
                <input type="text" v-model="nuevoAutor"><br>
                <input type="text" v-model="nuevaPregunta"><br>
                <button @click="agregarMensaje">Agregar</button>

            </div>
            
            <div class="box" v-for="pregunta in preguntas">
                {{pregunta.autor}}: {{pregunta.mensaje}}
            </div>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f5979a9a818681879485b5c0dbc5dbc7">[email protected]</a>/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
    <script src="js/vue.js"></script>
    <script src="js/index.js"></script>
</body>
</html>

Vue code:

const app = new Vue({
    el: "#app",
    data: {
        preguntas: [
            
        ],
        preguntasAprobadas: [
            
        ],
        nuevoAutor: "",
        nuevaPregunta: "",
        boxes: []
        
    },
    methods: {
        agregarMensaje: function(){
            this.preguntas.unshift({
                autor: this.nuevoAutor,
                mensaje: this.nuevaPregunta,
                publicado: false
            });
            this.nuevaPregunta = "";
            this.nuevoAutor = "";
            boxes = document.querySelectorAll(".box");
            this.agregarClase();
            
            
        },
        agregarClase: function(){
                boxes[0].className += " animation";
                
        }
    }
})

CSS code:

.box {
    width: 100%;
    background-color: rgb(255, 224, 174);
    border: 1px solid rgb(255, 210, 137);
    padding: 20px;
    margin-top: 30px;
    min-height: 200px;
}

.animation {
    animation: show 5s;
    -webkit-animation: show 5s;
}

@keyframes show {
    0% { opacity: 0; }
    100% { opacity: 1; }

}

EDIT: The CSS has been simplified so that the style is applied correctly only to the latest element added at index 0.

.box {
    background-color: rgb(255, 224, 174);
    border: 1px solid rgb(255, 210, 137);
    padding: 20px;
    margin-top: 30px;
    min-height: 200px;
    width: 100%;
    opacity: 1;
    animation: show 1s;
    -webkit-animation: show 1s;
}


@keyframes show {
    0% { 
        width: 1%;
        opacity: 0; 
    }
    100% { 
        width: 100%;
        opacity: 1; 
    }

}
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Preguntas en vivo</title>
    <link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f1939e9e858285839081b1c4dfc1dfc3">[email protected]</a>/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <link rel="stylesheet" href="css/style.css">

</head>
<body>

    <div id="app">
        <div class="mt-5 d-flex flex-column align-items-center container">
            <div>
                <input type="text" v-model="nuevoAutor"><br>
                <input type="text" v-model="nuevaPregunta"><br>
                <button @click="agregarMensaje">Agregar</button>

            </div>
            
            <div class="row box" v-for="pregunta in preguntas">
                <div class="col-12">
                    {{pregunta.autor}}: {{pregunta.mensaje}}
                </div>
            </div>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="accec3c3d8dfd8decddcec99829c829e">[email protected]</a>/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
    <script src="js/vue.js"></script>
    <script src="js/index.js"></script>
</body>
</html>

Answer №1

If you're in search of the vue component called transition-group, check out the documentation.

This component adds CSS classes as elements are added, removed, or reordered, allowing for seamless animations.

Take a look at this sample code:

<template>
  <div id="app">
    <transition-group name="fade" class="questions" mode="in-out">
      <div v-for="question of questions" :key="question.id" class="item">
        {{ question.msg }}
      </div>
    </transition-group>
    <button @click="addQuestion">Add question</button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      questions: [
        { id: 1, msg: 'Hey'},
        { id: 2, msg: 'there'},
        { id: 3, msg: 'General'},
        { id: 4, msg: 'Kenobi'},
      ],
    }
  },
  methods: {
    addQuestion () {
      const newId = Math.floor(Math.random() * 1000 + 4)
     const newQuestion = { id: newId, msg: 'New question' + newId }
     this.questions.push(newQuestion) 
    }
  }
}
</script>

<style>
#app {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  max-width: 300px;
  margin: 0 auto;
  height: 80vh;
}
.questions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.questions .item {
  background: #fafafa;
  border: 1px solid lightgray;
  text-align: center;
  min-width: 130px;
  padding: 4px 12px;
}

// Fade animation for each item
.item.fade-enter-active {
  transition: opacity 1s;
}
.item.fade-enter, .item.fade-leave-to {
  opacity: 0;
}
</style>

Each time you add or remove an item, this CSS transition will be applied automatically. The same goes for when items are removed (refer to the fade-leave-to class)

Check out this example on CodePen

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

When using JSON.stringify on a map object, it returns an empty result

var map1= new Map(); map1.set("one",1); var map2 = new Map(); map2.set("two",2); concatMap = {}; concatMap['one']= map1; concatMap['two']= map2; JSON.stringify(concatMap); //outputs : "{"one":{},"two":{}}" I als ...

The secrets behind the seamless, fluid layout of this website

Upon exploring the website www.emblematiq.com, I noticed that it features a fluid/liquid layout. Despite analyzing the code, I am unable to decipher how this effect is achieved. The layout appears to be fixed width with the canvas element set at 1180px. D ...

What is the method to execute jQuery code after the completion of a fade out effect?

I am attempting to fade out a div upon click while also adjusting some CSS properties. The problem I am encountering is that the CSS properties change during the fade out transition, instead of after it has completed. I would like the values to change onc ...

How do I customize the rounding and color of selected dates in Vue Tailwind Datapicker?

I am looking to give the selected data a more square rounding. Additionally, I need help with specifying colors in the tailwind.config file that will be compatible with this component. The vtd-primary color currently does not work. https://i.sstatic.net/S ...

What is the best way to use a generic callback function as a specific argument?

TS Playground of the problem function callStringFunction(callback: (s: string) => void) { callback("unknown string inputted by user"); } function callNumberFunction(callback: (n: number) => void) { callback(4); // unknown number inputt ...

Managing state changes with a slider in ReactJS

I am currently working with the Foundation slider found at this link: click for doc. To access the slider's current value, they recommend using a hidden input like this: <div class="slider" data-slider data-initial-start="50" data-end="200"> & ...

Removing a parameter from a link in Vue.js: A step-by-step guide

I currently have the following list of URLs: http://example.com/post?st=1&plt=123&number=1 http://example.com/post?st=1&plt=[exp]&number=1 http://example.com/post/view/12?ex=1&plt=123 http://example.com/post/edit/12?ex=1&tes ...

The Google Language Translator disregards the formatting

Currently, I am in the midst of developing a website with Wordpress and have successfully integrated Google Language Translator. Everything seems to be working well, except for one issue - when I translate the content, it alters the font size. Prior to tra ...

Combining array of objects by various identifiers

I'm facing a situation like this: const idMappings = { // id: parentId "2": "1", "3": "1" } const inputData = [ { id: "1", data: [1], }, { id: "2", data: [2] }, { ...

Both if and else statements are carrying out code in JavaScript/jQuery

The second if statement is functioning correctly, but the first one always triggers the else statement and never stands alone. This jQuery function is enclosed within another function that is invoked under the "$(document).ready" command. I resorted to u ...

Is there a more efficient method for implementing server side rendering in a Next.js application?

Currently, I am implementing server-side rendering in my Next.js application. This specific component is responsible for returning HTML content. I'm wondering if there are more efficient methods available? import Feature from 'components/home/Fea ...

Click event to focus on AngularJS TinyMCE textarea

My current project utilizes the tinymce text editor in combination with the angularJS framework. I obtained the directive from here and successfully integrated the editor using the provided example on GitHub! Initially, everything was working smoothly wit ...

Using GraphicsMagick in combination with Node.js to upload a fresh image file to AWS S3: A step-by-step guide

I've encountered an issue while trying to upload images to S3 - phone images appear rotated due to EXIF data. To address this problem, I came across a tool called graphicsmagick which claims to remove EXIF data and resize images to 500px wide. However ...

How to position a popup window perfectly in the center without having direct access to the popup code

Currently, I am faced with the challenge of using software that does not allow direct editing of HTML on individual pages. Instead, I have the ability to add code to the header and footer to make modifications to the content within the body of each page. ...

Using JavaScript to empty input field when switching focus between input fields

I am experiencing an issue with clearing a input number field. Here is the code snippet in question: <input class="quantity_container" v-model="length.quantity" type="number" pattern="[0-9]*" inputmode="numeric" onfocus="if (this.value == &ap ...

Strategies for Applying Filters in Search Feature on IOS Devices

Currently, I have an array of books that are being displayed on my view. At the top of the view, there are 3 filters available: (All | Reading level 1 | Reading Level 2 | Reading Level 3) (All | Informational | Literature) (All | Published in 2000-2005 | ...

Using an icon font as a background in CSS attribute

I am struggling to replace a background image in CSS with an icon font instead of an icon image. I have been unable to accomplish this task. Here is the CSS property I am working with: .social-networks .twitter{background:url(../images/social/twitter.png) ...

What are the different applications of npm packages?

Is it possible to use npm packages in any Javascript runtime environment? I have experience using them in Angular and Node, but are they universally compatible across all environments? Edit: To those who downvoted this post, as a newcomer seeking assistan ...

Changes to a key value are not reflected in the array of objects

When making changes to input fields within an array of records that include Date and Text fields in a table, the data is not updating as expected. I am encountering issues where changing the Date input results in undefined Text values, and vice versa. My g ...

Using Java beans to present form data utilizing session

How can I utilize Java Beans and session beans to store user input data and display a preview of the entered details on the next page? I have already created a servlet using JSP, but now I want to incorporate Java Beans to showcase the form data. How shoul ...