Smoothly animate between alignment values
The Solution at a Glance
- CSS doesn’t smoothly animate changes between alignment values like
: flex-start
and: flex-end
. - Store the position and size of the flex items before and after you change the alignment value.
- Manually animate between the old and new positions with
Element.animate()
. - This only works if your flex items are DOM elements. It won’t work for pseudo-elements, because you can’t select them with JavaScript.
CSS doesn’t smoothly animate changes between keyword values
Flexbox lets you smoothly animate changes in numbers. For example, you could animate your flex item’s size from 100 pixels to 200 pixels, and that animation would be smooth.
But you don’t get the same smooth animation with keyword values. For example, it wouldn’t work if you went from : flex-start
to : flex-end
in your flex container.
But the cool thing about those keywords is you don’t need to deal with numbers. You just tell the browsers where boxes should go at a high level.
You can keep using those values, but you’ll have to to animate changes between them manually.
Store the old and new position and size of flex items
Use Element.getBoundingClientRect()
to get the size and position of each flex item.
Then, change the alignment value. For example, from : flex-start
to : flex-end
.
Immediately after that, use Element.getBoundingClientRect()
again to get the new size and position of each flex item.
Animate flex items with Element.animate()
If you don’t do anything, your flex items will simply switch from : flex-start
to : flex-end
without any animation.
But because we saved the position and size of all the flex items before and after we made the change, we can manually animate between them.
We’re not animating between keyword values like flex-start
and flex-end
anymore. Instead, we’re animating between cold, hard pixels we got from Element.getBoundingClientRect()
. Because of that, we’ll get a beautiful, smooth animation.
We’ll call Element.animate()
on each flex item element, and animate from the old position and size to the new position and size.
This is called the FLIP technique, and you can learn more about it here: https://css-tricks.com/animating-layouts-with-the-flip-technique/.
This only works for DOM elements
Flex item boxes generated by pseudo-elements only exist in the box tree. They don’t exist in the DOM tree at all. Because JavaScript can only select things in the DOM tree, it can’t select pseudo-elements.
This is true for anonymous flex items, too. For example, if you have a button
element and lay out the text in it with Flexbox. Flex items are boxes, and text in the DOM tree generates a text run, not a box.
So Flexbox wraps the text run in an anonymous box, and that box becomes the flex item. Because this box only exists in the box tree and not the DOM tree, you can’s select it and animate it with JavaScript.
But if you wrap your text in a span
element, then the span
element will generate the flex item box, and you’re good to go.