Interpolation (tweening)
The math that fills the gap between two values so an element moves through every step from A to B instead of snapping.
See it
What it is
Interpolation is the arithmetic every animation runs on: you declare a start value and an end value, and the engine computes all the values in between, one per frame. The animation term for it is tweening, borrowed from the Disney studio system where senior animators drew the key poses and 'inbetweeners' drew the frames connecting them.
The simplest form is linear interpolation (lerp): value = start + (end - start) * t, where t runs 0 to 1. Everything else is a layer on top. An easing function reshapes t before the lerp, which is why easing and interpolation are different jobs: easing decides the pacing, interpolation decides the value. Springs replace the whole thing with a physics solver instead of a t.
Gotcha: not every property interpolates. Browsers tween numbers, lengths, colors, and transform lists, but 'background-image' and most keyword values are discrete: they flip at the halfway mark with no in-between. 'display' is the famous exception to that exception. It is discrete too, but once discrete transitions are switched on with 'transition-behavior: allow-discrete', the browser deliberately holds a 'display: none' element visible for the whole transition and flips at the far end instead of the middle, which is the only reason popovers and dialogs can animate closed. Colors also depend on the space you interpolate through (sRGB versus OKLCH), which is why some gradients and fades go muddy grey in the middle.
Ask AI for it
Animate this value by interpolating between an explicit start and end state rather than toggling it: define the two states, tween every animatable property between them (position, scale, opacity, color) over 400ms, and apply an ease-out curve to the progress value so the pacing is not linear. Interpolate colors in OKLCH so the midpoint stays saturated. Leave discrete properties like 'display' out of the tween, and if the element has to disappear at the end, handle that separately with 'transition-behavior: allow-discrete' rather than trying to interpolate it.