keyframe animation using pseudo selectors

1.5k views Asked by At

How would I properly animate a div with a pseudo selector without out the animation skipping back to the main animation of the div and then playing the animation assigned to the pseudo selector.

The element in question is the red circle, that simply needs to move upwards by (X)amount, instead of moving back then moving up.

I have attached a fiddle and coding for this question.

.blobs {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: white;
  width: 900px;
  height: 200px;
  margin: auto;
}
.blob {
  background: grey;
  width: 100px;
  height: 100px;
  position: absolute;
  left: 50%;
  top: 50%;
  margin-top: -50px;
  margin-left: -50px;
  border-radius: 100%;
  text-align: center;
  line-height: 70px;
}
@keyframes blob-anim-red {
  0% {
    transform: translateX(0px);
  }
  100% {
    transform: translateX(100px);
    animation: forwards;
  }
}
@keyframes blob-anim-blue {
  0% {
    transform: translateX(0px);
  }
  100% {
    transform: translateX(200px);
  }
}
@keyframes blob-anim-green {
  0% {
    transform: translateX(0px);
  }
  100% {
    transform: translateX(300px);
  }
}
.blob:nth-child(2) {
  animation: blob-anim-red cubic-bezier(1, .01, 0, 1) 0.5s forwards alternate;
  background: rgba(255, 0, 0, .3);
}
@keyframes move-up {
  0% {
    transform: translateY(0px);
  }
  100% {
    transform: translateY(-10px);
  }
}
.blob:nth-child(2):hover {
  /*transform:translateY:(20px);*/
  animation: move-up cubic-bezier(1, .01, 0, 1) 0.5s alternate;
  transition: transform 0.3s, color 0.3s, background 0.3s;
  color: #fff;
  background: rgba(255, 0, 0, 0.8);
}
.blob:nth-child(3) {
  animation: blob-anim-blue cubic-bezier(1, .01, 0, 1) 0.5s forwards alternate;
  background: rgba(0, 255, 0, .3);
}
.blob:nth-child(4) {
  animation: blob-anim-green cubic-bezier(1, .01, 0, 1) 0.5s forwards alternate;
  background: rgba(0, 0, 255, .3);
}
.blob:first-child {
  background: #ccc;
}
<body>
  <div class="help"></div>
  <div class="blobs">
    <div class="blob">
      <p>1st Child</p>
    </div>
    <!-- 1st child-->
    <div class="blob">
      <p>2nd Child</p>
    </div>
    <!-- 2nd child-->
    <div class="blob">
      <p>3rd Child</p>
    </div>
    <!-- 3rd child-->
    <div class="blob">
      <p>4th Child</p>
    </div>
    <!-- 4th child-->
  </div>
</body>

JsFiddle

1

There are 1 answers

2
Nico O On BEST ANSWER

Your animation that you trigger on :hover overrides the transform property of the red circle, hence it looks like the whole animation was reset. One idea to overcome this to use margin instead of transform: translate or just copy the final transform property a second time.

Here is one way of doing it, using the margin property for the animation that is being fired on :hover. This solution is using simple transitions instead of a animation.

.blobs {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: white;
  width: 900px;
  height: 200px;
  margin: auto;
}
.blob {
  background: grey;
  width: 100px;
  height: 100px;
  position: absolute;
  left: 50%;
  top: 50%;
  margin-top: -50px;
  margin-left: -50px;
  border-radius: 100%;
  text-align: center;
  line-height: 70px;
}
@keyframes blob-anim-red {
  0% {
    transform: translateX(0px);
  }
  100% {
    transform: translateX(100px);
    animation: forwards;
  }
}
@keyframes blob-anim-blue {
  0% {
    transform: translateX(0px);
  }
  100% {
    transform: translateX(200px);
  }
}
@keyframes blob-anim-green {
  0% {
    transform: translateX(0px);
  }
  100% {
    transform: translateX(300px);
  }
}
.blob:nth-child(2) {
  animation: blob-anim-red cubic-bezier(1, .01, 0, 1) 0.5s forwards alternate;
  background: rgba(255, 0, 0, .3);
  /*relevant change 1*/
  transition-property: margin, color;
  transition-duration: 0.3s;
}

.blob:nth-child(2):hover {
  /*relevant change 2*/
  margin-top: -90px;
  color: #fff;
  background: rgba(255, 0, 0, 0.8);
}
.blob:nth-child(3) {
  animation: blob-anim-blue cubic-bezier(1, .01, 0, 1) 0.5s forwards alternate;
  background: rgba(0, 255, 0, .3);
}
.blob:nth-child(4) {
  animation: blob-anim-green cubic-bezier(1, .01, 0, 1) 0.5s forwards alternate;
  background: rgba(0, 0, 255, .3);
}
.blob:first-child {
  background: #ccc;
}
<body>
  <div class="help"></div>
  <div class="blobs">
    <div class="blob">
      <p>1st Child</p>
    </div>
    <!-- 1st child-->
    <div class="blob">
      <p>2nd Child</p>
    </div>
    <!-- 2nd child-->
    <div class="blob">
      <p>3rd Child</p>
    </div>
    <!-- 3rd child-->
    <div class="blob">
      <p>4th Child</p>
    </div>
    <!-- 4th child-->
  </div>
</body>