Challenges in layout animations

Before we dive deeper into layout animations, let’s address some common quirks you may encounter. In this lesson, we’ll cover the most frequent challenges:

  1. Scale distortion & jumping child elements
  2. Animating inline elements (e.g. span)
  3. Border radiuses
  4. Animating text
  5. Restricting layout animations

1. Scale distortion & jumping child elements

Powered by Mux

As you’ve likely seen in earlier examples, child elements of a parent with layout animations can become distorted during the animation process. They may scale weirdly or move to unexpected positions.

Take a look at the example below. Clicking the square changes its size in both directions, then in only one, before returning to its original size. Notice how the circle in the center stretches oddly, even though the parent motion.div has the layout prop.

Try clicking it a few times.

import { useState, useMemo } from "react";
import { motion } from "framer-motion";

const steps = ['start', 'larger', 'wider'];

export const App = () => {
  const [stepIndex, setStepIndex] = useState(0);
  const stepName = useMemo(() => steps[stepIndex], [stepIndex]);

  return (
    <div className="grid place-items-center min-h-dvh grid-cols-1 grid-rows-1">
      <motion.div
        layout
        onClick={() => setStepIndex(stepIndex => (++stepIndex % steps.length))}
        style={{
          width: stepName !== 'start' ? 200 : 100,
          height: stepName === 'larger' ? 200 : 100,
        }}
        className="bg-white p-6 cursor-pointer">
        <div className="bg-black rounded-full w-12 h-12" />
      </motion.div>
    </div>
  );
};

export default App;

Preventing the distortion

This distortion happens because the parent element is scaling during the resize. As a result, the child elements also get scaled.

Framer Motion can apply a “counter-transform” to child elements, which inverses the scale and corrects the distortion. To enable this, the child element must also be a motion element with the layout prop.

Try adding the motion element with layout prop to the child element in the playground above, and watch how this resolves the issue. I’ll demonstrate this in the video above as well.

2. Animating inline elements (e.g. span)

Unlock this video and the rest of this course by joining Frontend.FYI PRO .

Framer Motion uses CSS transforms for most animations, but transforms don’t work on elements with display: inline. As a result, animations can break if applied to inline elements like <span>.

Unlock the full lesson with PRO

Want to read the full lesson? Join Frontend.FYI PRO.

PRO is a one time purchase of €149 that gives you lifetime access to this course, any courses released in the future, and so much more!