CSS - Animation whole ul and not just first row when new item enters

Viewed 419

Take a look at this simple JsFiddle I made which is animating new items that enter the list.

However, the animation only affects for the first row, and not for all of the rows. I made the colors random, so you can actually see the "jumps" on the other rows, when a new item is being inserted.

Is there a way to make it it affect all rows just with CSS?

@keyframes enter {
  0% {
    transform: translateX(-100%);
    margin-left: calc(var(--w) * -1);
  }
  100% {
    transform: translateX(0px);
    margin-left: 0
  }
}

This is my animation, and this is my list item:

.slidepush li {
  --w: 50px;
  width: var(--w);
  height: 50px;
  background-color: red;
  vertical-align: top;


  border: 0;
  padding: 0;
  margin: 0;
  display: inline-block;
}

.enter {
  animation: enter 1s;
}

Ceated a simple class that manages the ul and implements add:

class SlidePush {

    constructor(ulElement) {
    this.element = ulElement;
  }

  add(item) {
    this.element.prepend(item.addClass('enter'));
  }
}

const sp = new SlidePush($(".slidepush"));

setInterval(() => {//
  var colors = ['red', 'blue', 'green', 'black'];
  var color = colors[Math.floor(Math.random() * colors.length)];
  sp.add($("<li style='background-color:" + color +" !important;'></li>"));
}, 1000);
2 Answers

You can add the animation considering nth-child so you add to always the first one on each row. You need to also remove the animation after it's done to be able to add it again to the same element when it reach the next row.

class SlidePush {

 constructor(ulElement) {
   this.element = ulElement;
  }
  
  add(item) {
   this.element.prepend(item);
    $('.slidepush li:nth-child(4n+1)').addClass('enter');
    setTimeout(function(){ $('.slidepush li:nth-child(4n+1)').removeClass('enter') }, 1000);
  }
}

const sp = new SlidePush($(".slidepush"));

setInterval(() => {//
var colors = ['red', 'blue', 'green', 'black'];
var color = colors[Math.floor(Math.random() * colors.length)];
sp.add($("<li style='background-color:" + color +" !important;'></li>"));
}, 1200);
div {
--w: 200px;
  max-width: var(--w);
}


.slidepush {
  list-style: none;
  border: 0;
  padding: 0;
  margin: 0;
  display: table;
  }

.slidepush li {
  --w: 50px;
  width: var(--w);
  height: 50px;
  background-color: red;
  vertical-align: top;

  
  border: 0;
  padding: 0;
  margin: 0;
  display: inline-block;
}
      
.enter {
  animation: enter 1s;
  position:relative;
  z-index:-1;
}
      
@keyframes enter {
  0% {
    transform: translateX(-100%);
    margin-left: calc(var(--w) * -1);
  }
  100% {
    transform: translateX(0px);
    margin-left: 0;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <ul class="slidepush">

  </ul>
</div>

Could you try the following code.

class SlidePush {

  constructor(ulElement) {
    this.element = ulElement;
  }

  add(item) {
    $('.slidepush li').removeClass('enter');
    $('.slidepush li').removeClass('push');
    $('.slidepush li:nth-child(4n+1)').addClass('push');
    this.element.prepend(item.addClass('enter'));
  }
}

const sp = new SlidePush($(".slidepush"));

setInterval(() => { //
  var colors = ['red', 'blue', 'green', 'black'];
  var color = colors[Math.floor(Math.random() * colors.length)];
  sp.add($("<li style='background-color:" + color + " !important;'></li>"));
}, 1000);
div {
  --w: 200px;
  max-width: var(--w);
}

.slidepush {
  list-style: none;
  border: 0;
  padding: 0;
  margin: 0;
  display: table;
}

.slidepush li {
  --w: 50px;
  width: var(--w);
  height: 50px;
  background-color: red;
  vertical-align: top;
  border: 0;
  padding: 0;
  margin: 0;
  display: inline-block;
}

.enter {
  animation-name: enter;
  animation-duration: 1s;
  animation-fill-mode: forwards;
}

.push {
  animation-name: push;
  animation-duration: 1s;
  animation-fill-mode: forwards;
}

@keyframes push {
  0% {
    margin-left: calc(var(--w) * -1);
  }
  100% {
    margin-left: 0
  }
}

@keyframes enter {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(0px);
  }
}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<div>
  <ul class="slidepush">

  </ul>
</div>

Related