Simone
Simone

Reputation: 21262

How to prevent animation only on last child

I have a growing list of divs. The user can click a button to append a new div to the bottom.

This list has a fade-in animation, this is so that the user can see when the list has been loaded (it gets data from a server).

When a new row gets added, I’d like to not have the fade-in animation.

I tried using:

div:last-child {
  animation: none;
}

This works only the first time a new div has been added. On all the following additions, the animation gets applied regardless.

Please check this demo below to see what I mean:

function addRow(text) {
  var d = document.createElement('div');
  d.innerHTML = text;
  var root = document.querySelector('main');
  root.appendChild(d);
}
body {
  background: #222;
}

main > div {
  background: #444;
  border: 1px solid green;
  animation: fade-in 1s;
}

div:last-child {
  background: #999;
  animation: none;
}

@keyframes fade-in {
  from { opacity: 0 }
  to { opacity: 1 }
}
<main>
  <div>1</div>
  <div>2</div>
  <div>3</div>
</main>
<button type="button" onclick="addRow('hello')">Add row</button>

How do I ensure the animation runs on the whole list the first time, but prevent it on subsequent additions?

Upvotes: 6

Views: 438

Answers (2)

Temani Afif
Temani Afif

Reputation: 272817

How do I ensure the animation runs on the whole list the first time

Simply apply it to the whole list

function addRow(text) {
  var d = document.createElement('div');
  d.innerHTML = text;
  var root = document.querySelector('main');
  root.appendChild(d);
}
body {
  background: #222;
}

main > div {
  background: #444;
  border: 1px solid green;
}
main {
  animation: fade-in 1s;
}

@keyframes fade-in {
  from { opacity: 0 }
  to { opacity: 1 }
}
<main>
  <div>1</div>
  <div>2</div>
  <div>3</div>
</main>
<button type="button" onclick="addRow('hello')">Add row</button>

Upvotes: 0

Alvaro Montoro
Alvaro Montoro

Reputation: 29645

One option changing a little bit the JS and CSS:

  1. Add a class to the newly added elements to the list

    d.className = "added";
    
  2. Apply the animation only to the div that don't have that class

    main > div:not(.added) {
      animation: fade-in 1s;
    }
    

The initial div don't have that class, so they will be animated when the page loads, but the div that are added later (with the class name you specified) don't have any animation.

Here is a demo on how it would be based on your code:

function addRow(text) {
  var d = document.createElement('div');
  d.className = "added";
  d.innerHTML = text;
  var root = document.querySelector('main');
  root.appendChild(d);
}
body {
  background: #222;
}

main > div {
  background: #444;
  border: 1px solid green;  
}

main > div:not(.added) {
  animation: fade-in 1s;
}

div.added:last-child {
  background: #999;
}

@keyframes fade-in {
  from { opacity: 0 }
  to { opacity: 1 }
}
<main>
  <div>1</div>
  <div>2</div>
  <div>3</div>
</main>
<button type="button" onclick="addRow('hello')">Add row</button>

Upvotes: 4

Related Questions