CSS offers no way to do this, so you have to calculate the duration in JavaScript yourself and set it.
For example, consider this animation (with a fixed duration and, therefore, with a variable speed):
@keyframes slideball { 0% { margin-left: 0px; } 100% { margin-left: calc(100% - 30px); } } .slider { height: 30px; background: blue; border-radius: 20px; margin: 10px; padding: 5px; } #slider1 { width: 80px; } #slider2 { width: 200px; } #slider3 { width: 500px; } .ball { height: 30px; width: 30px; border-radius: 30px; background: red; animation: slideball linear 10s forwards; }
<div id="slider1" class="slider"> <div class="ball"></div> </div> <div id="slider2" class="slider"> <div class="ball"></div> </div> <div id="slider3" class="slider"> <div class="ball"></div> </div>
Suppose we want all the balls to move at a speed of 40 pixels per second, regardless of the width of the slider in which they are located. Then we can calculate the resulting animation duration in JavaScript and set the animation style property from JavaScript:
function startAnimation(slider) { const ball = slider.children[0], speed = 40,
@keyframes slideball { 0% { margin-left: 0px; } 100% { margin-left: calc(100% - 30px); } } .slider { height: 30px; background: blue; border-radius: 20px; margin: 10px; padding: 5px; } #slider1 { width: 80px; } #slider2 { width: 200px; } #slider3 { width: 500px; } .ball { height: 30px; width: 30px; border-radius: 30px; background: red; }
<div id="slider1" class="slider"> <div class="ball"></div> </div> <div id="slider2" class="slider"> <div class="ball"></div> </div> <div id="slider3" class="slider"> <div class="ball"></div> </div>
Yes, this is a bit verbose and annoying, especially because calculating the distances traveled when you have a bunch of fields, indents and borders, and such things can sometimes get a little ... confusing. But CSS does not currently offer you the best tool to use, so you are stuck with such approaches.
Mark amery
source share