HomeGuideLabGlossary

Smoothly animate between alignment values

The Solution at a Glance

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.

width: 140height: 721x: 128y: 100Viewport

Then, change the alignment value. For example, from : flex-start to : flex-end.

1Viewportjustify-content: flex-start

Immediately after that, use Element.getBoundingClientRect() again to get the new size and position of each flex item.

width: 140height: 721x: 0y: 100Viewport

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.

1111

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.

.flex-container#bananaDOM TREE.flex-container::before#bananaBOX TREE

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.

.flex-container"Cherry"DOM TREE.flex-containerBOX TREE"Cherry"

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.

.flex-containerspan"Cherry"DOM TREE.flex-containerspanBOX TREE"Cherry"