You don’t need an animation library

View Transitions are awesome. I love to see examples of view transitions that show how they can genuinely improve user experience by helping communicate what is happening.

But what about interactive components? Little animated touches, when done right, make interfaces feel more responsive and fun. Most micro interactions can be handled with CSS transitions and animations but I was curious whether view transitions deserve a place in the design engineer’s toolbelt for component-level animation too.

The example: “arrange the words” UI

If you use Duolingo, yo’ve seen this type of excercise type where you need to translate phrases by arranging the English words in the right order:

This kind of animation used to take tons of JavaScript and was often impractical for performance reasons. Words move between two containers, the remaining items reflow to fill the gaps, and every position change needs to animate. You would typically reach for a FLIP-based library like GSAP Flip or motion/react to track positions and interpolate between them.

Setup

To match the Duolingo example, we need two containers:

<div id="sentence-container">
  <!-- words will be moved here -->
</div>

<div id="word-container">
  <button class="word">We</button>
  <button class="word">like</button>
  <button class="word">learning</button>
</div>

All that is needed to animate the movement of a word is to move it from one container to the other and wrap it in startViewTransition:

document.startViewTransition(() => {
  sentenceContainer.appendChild(wordElement);
});

Nos gusta aprender sobre View Transitions.

Nice!

The standard animation is a crossfade. If we want the words to move to their new position, each word needs to have a view-transition-name. For same-document view transtions, we can use match-element to derive a unique name from the element identity:

.word {
  view-transition-name: match-element;
}

Nos gusta aprender sobre View Transitions.

Nice!

Much better. But in the Duolingo example, there are visible visible gaps where the words used to be. If we add a wrapper element around each word and assign it a fixed width, we can get a similar effect:

Nos gusta aprender sobre View Transitions.

Nice!

That’s it! The browser snapshots the element’s position before and after the DOM update and animates between the two. No FLIP animation library needed.

Where it breaks down

You may have already spotted this but see what happens if you try to click the words fast one after another in this slowed down example:

Nos gusta aprender sobre View Transitions.

Nice!

As you can see, the animation is blocking interaction while it’s ongoing. This happens because view transitions replace the page with screenshots while animating, so pointer events are blocked until the transition settles. Unfortunately, this is a deal breaker for many scenarios. If you need interruptible animations, your best bet as of the time of writing this is to use a FLIP animation library.

Conclusion

View transitions work well for interactions where only one thing moves at a time and the user waits for it to land: toggling a single item between states, expand/collapse, reordering with one drag at a time. They fall apart when the interaction is fast or concurrent — rapid tapping, anything where you need to interrupt mid-flight.

The core limitation is structural. View transitions work by taking a snapshot, animating, then resolving. There is no mid-flight interruption or blending. For interactions that need that, a FLIP animation library or the Web Animations API directly is still the right tool.

One thing to watch: scoped view transitions (Chrome 140, behind a flag) let you call element.startViewTransition() on any element, with pointer events only blocked within that subtree rather than the whole page. That helps when you have independent UI regions animating separately, but it does not help here since all the words share the same container as their transition root. View transitions became Baseline available in October 2025, so no polyfill or library needed.