1

I have posted before about CSS Keyframe animation and tried a different way of using delays.

I had css continous slider of 5 divs which worked fine. However I needed to remove two of the divs so there is only three.

.wrapper{
    position: relative;
    height: 330px;
    display: grid;
    overflow: hidden;
    width:600px;
    background:#f1f1f1;
}

.slide {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  animation: slider 9s cubic-bezier(0.5, 1, 0.5, 1) infinite;
  color:#fff;
  font-size:30px;
  text-align:center;
  padding-top:25%;
}

.slide:first-of-type {
  animation-delay: -9s;
  background:red;
}
.slide:nth-of-type(2) {
  animation-delay: -6s;
  background:blue;
}
.slide:last-of-type {
  animation-delay: -3s;
  background:black;
}

@keyframes slider {
  0% {
    transform: translateX(0);
    opacity: 1;
  } 
  16% {
    transform: translateX(0);
    opacity: 1;
  } 
  20% {
    transform: translateX(100%);
    opacity: 1;
  } 
  75% {
    transform: translateX(100%);
    opacity: 0;
  } 
  76% {
    transform: translateX(-100%);
    opacity: 0;
  } 
  96% {
    transform: translateX(-100%);
    opacity: 1;
  } 
}
<div class="wrapper">
  <div class="slide">
    1
  </div>
    <div class="slide">
    2
  </div>
    <div class="slide">
    3
  </div>
</div>

Link to my on going codepen.

So I have tried changing the animation to 9s, 3 seconds per div. I have changed the delay on the divs to -9s, -6s, -3s respectively but I have a pause in between each div sliding in.

I have tried to alter the percentages which is where I believe I am going wrong.

I am wondering if anyone can give me some help on the percentages I need to change or if there is a formula to use so I can switch up the amount of divs in the future if need be?

Jools
  • 81
  • 1
  • 12
  • Your code only has 3 divs. Why mention you have 5 when you only have 3? If you are only sliding one image out and sliding another image in, you only need %s for 0% and 100%. Intermediate % values are only necessary if you want to change the behavior at specific points during the animation. – TylerH Jun 02 '20 at 17:51
  • @TylerH sorry for the confusion about the number of divs Im referring to, I have edited the question in that respect. In terms of the animation I need one to slide in and momentarily wait then slide out whilst the next div slides in seamlessly and have it continously looping around. So that was why I had these intermediate % values. – Jools Jun 02 '20 at 18:08

1 Answers1

2

The keyframe percentages relate to your animation duration. For example: with a 10 second animation, 10% is the 1 second mark, 50% the 5 second mark, and 100% the 10 second mark.

If your entire animation is 9 seconds long and you have 3 slides that all start with an offset of 3 seconds, then you'll want to make sure that your slides do their thing in the first 33.33% (3 seconds) of the key-frame animation and stay hidden for the remaining 66.66% (6 seconds).

Now in your case the slide transitions aren't instant, so you'll have to go slightly beyond 33.33% to ensure that your animations overlap nicely without a gap. The delay you were seeing are these gaps.

So with that in mind you can simplify them like so:

@keyframes slider {
  /* Start left off screen */
  0% {
    transform: translateX(-100%);
  }
  /* Move to visible position within 8% of 9 seconds (less than a second). */
  8% {
    transform: translateX(0);
  } 
  /* Stay until at least 3 second mark (33% of 9s). */
  33.33% {
    transform: translateX(0);
  } 
  /* Move offscreen to the right while
     the next slide is moving in.
     Same duration as slide-in (8%), but starting at 33.33%,
     so 33.33% + 8% = 41.33%.
  */
  41.33% {
    transform: translateX(100%);
  } 
  /* Stay there until the end. */
  100% {
    transform: translateX(100%);
  }
}

Here a snippet:

.wrapper{
    position: relative;
    height: 330px;
    display: block;
    overflow: hidden;
    width:600px;
    background:#f1f1f1;
}

.slide {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  animation: slider 9s cubic-bezier(0.5, 1, 0.5, 1) infinite;
  color:#fff;
  font-size:30px;
  text-align:center;
  padding-top:25%;
}

.slide:first-of-type {
  animation-delay: -9s;
  background:red;
}
.slide:nth-of-type(2) {
  animation-delay: -6s;
  background:blue;
}
.slide:last-of-type {
  animation-delay: -3s;
  background:black;
}

.wrapper{
position: relative;
height: 330px;
display: block;
overflow: hidden;
width:600px;
background:#f1f1f1;
}

.slide {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  animation: slider 9s cubic-bezier(0.5, 1, 0.5, 1) infinite;
  color:#fff;
  font-size:30px;
  text-align:center;
  padding-top:25%;
}

.slide:first-of-type {
  animation-delay: -9s;
  background:red;
}
.slide:nth-of-type(2) {
  animation-delay: -6s;
  background:blue;
}
.slide:last-of-type {
  animation-delay: -3s;
  background:black;
}

@keyframes slider {
  /* Start left off screen */
  0% {
    transform: translateX(-100%);
  }
  /* Move to visible position within 8% of 9 seconds (less than a second). */
  8% {
    transform: translateX(0);
  } 
  /* Stay until at least 3 second mark (33% of 9s). */
  33.33% {
    transform: translateX(0);
  } 
  /* Move offscreen to the right while
     the next slide is moving in.
     Same duration as slide-in (8%), but starting at 33.33%,
     so 33.33% + 8% = 41.33%.
  */
  41.33% {
    transform: translateX(100%);
  } 
  /* Stay there until the end. */
  100% {
    transform: translateX(100%);
  }
}
<div class="wrapper">
  <div class="slide">
    1
  </div>
    <div class="slide">
    2
  </div>
    <div class="slide">
    3
  </div>
</div>

I do not think that you need the opacity changes, so I removed them.

You can, of course, change the percentages to increase/decrease the pause and speed of animation... just remember to make sure that the keyframes that show the slide have the same duration as the keyframes that hide it (in the example above 8%).

To add or remove slides in the future you can simply recalculate the percentages for that number of slides. So if you add 1 slide for a total of 4 you can work with 25% instead of 33.33%.

pschueller
  • 4,362
  • 2
  • 27
  • 50
  • thankyou! that wors perfectly. Also the explaination for future changes of the number of items in something like this is very helpful – Jools Jun 03 '20 at 08:29
  • I almost got it working with variables but I don't think you can use variables for keyframes-selectors which is necessary to calculate percentage. – jdf Feb 08 '22 at 08:58