Fjallbacka
Fjallbacka

Reputation: 474

Css keyframe animation only working for one element

I want to highlight the first row whenever a new one appears (im using vue.js so data is reactive) the problem is that my animation works only the first time data appears. The second time (and every next one) it doesn't work even though the appropriate css class is added on the DOM.

My vue template code:

  <v-container grid-list-xl>
      <v-data-table
        :disable-initial-sort="true"
        :rows-per-page-items="[10, 20, 30]"
        :headers="headers"
        :items="data_table"
        class="elevation-1"
      >
        <template v-if="loading" v-slot:no-data>
          <v-alert :value="true" color="warning" icon="warning">
            Trayendo datos del gateway, porfa esperate...
          </v-alert>
        </template>
        <template v-else v-slot:items="props">
          <tr>
            <td><strong>{{ props.item.time }}</strong></td>
            <td>{{ props.item.A }}</td>
            <td>{{ props.item.B }}</td>
            <td>{{ props.item.C }}</td>
          </tr>
        </template>
      </v-data-table>
  </v-container>

Using javascript I select the new row document.querySelector("tbody tr").className = "highlighted"; and the css class is this one:

.highlighted {
    -webkit-animation: fadeIt 2s ease-in-out;
    animation: fadeIt 2s ease-in-out; 

    @-webkit-keyframe fadeIt {
      0%   { background-color: #FFFFFF; }
      15%  { background-color: #FDFD99; }
      30%  { background-color: #FFFFFF; }
      45%  { background-color: #FDFD99; }
      60%  { background-color: #FFFFFF; }
      75%  { background-color: #FDFD99; }
      100% { background-color: #FFFFFF; }
    }

    @keyframes fadeIt {
      0%   { background-color: #FFFFFF; }
      15%  { background-color: #FDFD99; }
      30%  { background-color: #FFFFFF; }
      45%  { background-color: #FDFD99; }
      60%  { background-color: #FFFFFF; }
      75%  { background-color: #FDFD99; }
      100% { background-color: #FFFFFF; }
    }

My problem is not that it doesn't work. It is that it only works the first time data is changed.

To be noted, if I manually edit the html from browser debug tools and add the attribute class="highlighted" to any row, the animation works flawlessly.

Upvotes: 1

Views: 878

Answers (1)

Sumurai8
Sumurai8

Reputation: 20737

Your css simply seems to be invalid. You need to define the keyframes outside the class selector, which means you need to close the selector before defining the keyframes:

.highlighted {
  -webkit-animation: fadeIt 2s ease-in-out;
  animation: fadeIt 2s ease-in-out;
}

@-webkit-keyframe fadeIt {
  0% {
    background-color: #FFFFFF;
  }
  15% {
    background-color: #FDFD99;
  }
  30% {
    background-color: #FFFFFF;
  }
  45% {
    background-color: #FDFD99;
  }
  60% {
    background-color: #FFFFFF;
  }
  75% {
    background-color: #FDFD99;
  }
  100% {
    background-color: #FFFFFF;
  }
}

@keyframes fadeIt {
  0% {
    background-color: #FFFFFF;
  }
  15% {
    background-color: #FDFD99;
  }
  30% {
    background-color: #FFFFFF;
  }
  45% {
    background-color: #FDFD99;
  }
  60% {
    background-color: #FFFFFF;
  }
  75% {
    background-color: #FDFD99;
  }
  100% {
    background-color: #FFFFFF;
  }
}

Furthermore it is generally bad to do DOM manipulation yourself when Vue can do it for you. For example, the following example works just fine, even when adding the "highlighted" class on every row. After all, your animation only runs once.

<template>
  <div class="comp-child1">
    <div v-for="row in rows" :key="row.id" class="highlighted">{{ row.text }}</div>

    <button @click="addRow">Add row</button>
  </div>
</template>

<script>
export default {
  name: "child1",

  data() {
    return {
      rows: []
    };
  },

  methods: {
    addRow() {
      this.rows.push({
        id: this.rows.length,
        text: `Text for row ${this.rows.length}`
      });
    }
  }
};
</script>

<style>
.highlighted {
  -webkit-animation: fadeIt 2s ease-in-out;
  animation: fadeIt 2s ease-in-out;
}

@-webkit-keyframe fadeIt {
  0% {
    background-color: #FFFFFF;
  }
  15% {
    background-color: #FDFD99;
  }
  30% {
    background-color: #FFFFFF;
  }
  45% {
    background-color: #FDFD99;
  }
  60% {
    background-color: #FFFFFF;
  }
  75% {
    background-color: #FDFD99;
  }
  100% {
    background-color: #FFFFFF;
  }
}

@keyframes fadeIt {
  0% {
    background-color: #FFFFFF;
  }
  15% {
    background-color: #FDFD99;
  }
  30% {
    background-color: #FFFFFF;
  }
  45% {
    background-color: #FDFD99;
  }
  60% {
    background-color: #FFFFFF;
  }
  75% {
    background-color: #FDFD99;
  }
  100% {
    background-color: #FFFFFF;
  }
}
</style>

Edit css keyframe animation in vue

Upvotes: 1

Related Questions