stop motion-y css animations

css animations are really cool! they're super fun, versatile, and can be easily used to make any page more obnoxious.

however, another thing that css animations are, is very smooth. and this is great! it's not a problem for basically anyone, unless you're weird and want to have crappy, low fps animations on purpose.

and i do want that. i want my css animations to have a choppy framerate that makes them look like they're from a homemade stop motion animation. and css animations are not designed for that.

now, there does exist some functionality that gets you close to this effect. this is with the help of the steps() easing function.

i don't think i can explain easing functions elegantly, but i think just showing what the different easing functions do for css animations will explain more than enough (though i would highly recommend checking out the mdn docs about the subject):

ease-in-out:

steps(11):

linear:

so, from these it would seem that steps is the obvious answer for what i'm going for. it's exactly what i described, a css animation with a choppy framerate!

but it's not... great. as you can see from the examples above, the steps function is actually just the linear function divided into equal values. a lot of css animations don't look the best with just linear movement. so, is there any way to create a steps function that isn't linear? one much closer to the motion of the ease-in-out function?

ironically, the actual solution here lies within the linear function itself. i'm gonna link the mdn docs again for more details, but you can actually pass in parameters to the linear function to tell it what speed to travel at a given point of time. here's another example to better explain:

linear(0, .25, 1):

reaches 25% of total distance at halfway point in time

linear(0, .25 75%, 1):

reaches 25% of total distance at 3/4ths of total time

linear(0, .5 25% 75%, 1):

reaches 50% of total distance, and stays there from 25% to 75% of total time

you can give it a speed of zero for a set amount of time! that's a step!

what this means is that we can use the linear function to create our own custom steps function. i used the cubic bezier site to get some reference values to imitate the ease-in-out function, and created this monstrosity:

--easing-steps-11: linear(
	0 0% 9%,
	0.04 9% 18%,
	0.1 18% 27%,
	0.2 27% 36%,
	0.35 36% 45%,
	0.5 45% 55%,
	0.65 55% 64%,
	0.8 64% 73%,
	0.9 73% 82%,
	0.96 82% 91%,
	1 91% 100%);
			

yeesh. i'm glad i can at least hide this behind a variable.

so not the nicest solution, for several reasons. but this is what it looks like in action:

ease-in-out:

var(--easing-steps-11):

linear:

and that's it! that's exactly what i wanted this whole time. beautiful.

but again, it's really not the nicest solution. the linear function i just defined mimics the motion of ease-in-out. so if i wanted to mimic the motion of just ease-out, i'd have to create an entire new function.

and what about for different lengths of time? if you wanted to have animations with difference durations while keeping the same "framerate", you'd need a different number of steps for each one. that's a new function you'd have to define every time.

i do wish they would just add an additional parameter to the steps() function, allowing you to pass in a specific easing function to divide steps from instead of just linear. if you could just call steps(11, ease-in-out) then all of my weird niche problems would be solved!

anyway, this got a bit more complicated than i intended lol. hopefully it makes sense to anyone who finds this stuff interesting. not making any promises, but i may look into making a stylesheet with some reusable animations