motion icon indicating copy to clipboard operation
motion copied to clipboard

[BUG] Stagger animation does not occur when children has a "whileHover" animation

Open MaximeHeckel opened this issue 4 years ago • 12 comments
trafficstars

1. Read the FAQs 👇 ✅ 👍 2. Describe the bug

Hey there 👋 I found this little bug after updating from framer-motion 2.6.13 to 3.1.1. The following component had both a "stagger children" animation (very similar to the one provided in your documentation as an example) and each child also had a whileHover animation (hovering a child in the list would add some marginRight to it). While this used to work in Framer Motion 2.6.13, upgrading to 3.1.1 showcased a weird behavior: the stagger animation does not happen if the child has a whileHover animation

 const list = {
    hidden: { opacity: 0 },
    visible: {
      opacity: 1,
      transition: {
        // delayChildren: 1.5,
        staggerChildren: 0.15
      }
    }
  };

  const item = {
    hidden: { opacity: 0 },
    visible: { opacity: 1 },
    hover: {
      marginRight: "5px",
      transition: { ease: "easeOut" }
    }
  };

  return (
    <>
      <motion.ul
        style={{
          display: "flex",
          flexWrap: "wrap",
          marginLeft: "0px",
          marginBottom: "8px",
          marginTop: "15px"
        }}
        initial="hidden"
        animate="visible"
        variants={list}
      >
        {replies.map((reply) => (
          <motion.li
            key={reply.id}
            data-testid={reply.id}
            variants={item}
            /** Uncomment this to see the issue, this used to work in framer-motion 2.6.13! */
            // whileHover="hover"
          >
            foo
          </motion.li>
        ))}
      </motion.ul>
    </>
  );
};

3. IMPORTANT: Provide a CodeSandbox reproduction of the bug

Here's a full example showcasing this behavior on the latest version: https://codesandbox.io/s/practical-fermi-4f9k0?file=/src/App.js

4. Steps to reproduce

Steps to reproduce the behavior:

  1. Go to the codesandbox ☝️
  2. Notice the staggered animation occurs as expected 👍
  3. Uncomment the whileHover statement and refresh
  4. Notice that now, the whole list simply fades in, no staggered animation occurs

5. Expected behavior

I might be doing something wrong, and maybe my previous implementation simply worked out of sheer luck (totally possible), or maybe there's something wrong, but this is the only weird behavior that I've noticed after upgrading and I'd like to understand why it happens if it's not a bug.

Of course, this is not pressing at all, please enjoy your holidays first 🙏 consider this ticket as low priority

6. Video or screenshots

https://user-images.githubusercontent.com/2974412/103183308-7f605c00-487f-11eb-86c9-d11dd4fe1e92.mov

7. Environment details

Browser: Chrome OS: macOS Big Sur Framer Motion: 3.1.1

MaximeHeckel avatar Dec 28 '20 01:12 MaximeHeckel

if you want a workaround, you can set the whileHover prop without variants, and remove the "hover" object from the item variants

 whileHover={{
              marginRight: "5px",
              transition: { ease: "easeOut" }
            }}

https://codesandbox.io/s/practical-dan-xcsrx?file=/src/App.js

KirdesMF avatar Dec 28 '20 11:12 KirdesMF

Thank you @KirdesMF that's a good workaround!

MaximeHeckel avatar Dec 28 '20 15:12 MaximeHeckel

I believe what's happening here is the whileHover is making that motion component a new "variant-controlling" component and stopping it from receiving variants from parents. Maybe it's possible to do this on a per-prop basis

mattgperry avatar Jan 04 '21 13:01 mattgperry

An underlying problem here that might be a show-stopper is as I make this code more concurrent mode-safe one of the things I've had to do is make components in a given variant tree re-render whenever a parent does. If I made this work on a per-prop basis you'd essentially have the whole motion tree re-render whenever a variant changes.

mattgperry avatar Jan 05 '21 12:01 mattgperry

Ran into a similar issue when combining variants with animate={useAnimation()}. The following example stopped working since framer motion 3: https://codesandbox.io/s/romantic-solomon-qfm84?file=/src/App.tsx

jrmyio avatar Jun 16 '21 10:06 jrmyio

in my case, i had the same issue, even though i wasn't using a whileHover animation. And i figured out that children should not have a transition delay .

Mouad-Gh avatar Jun 07 '22 14:06 Mouad-Gh

Any updates on this issue?

vishnupeas avatar Jun 24 '22 16:06 vishnupeas

Also still waiting for updates on this. @mattgperry https://github.com/framer/motion/pull/921 mentioned it fixes this issue but it actually did not.

jrmyio avatar Aug 30 '22 08:08 jrmyio

For me it isn't working either. Using in conjunction with whileInView

bitsmyth avatar Oct 20 '22 21:10 bitsmyth

Yup not working with whileInView

mylesthedev avatar Jun 29 '23 21:06 mylesthedev

Any updates on this? It's not just the whileInView that is broken.

Variants in combination with useAnimation() also doesn't work.

jrmyio avatar May 23 '24 15:05 jrmyio

+1

mrpotato3 avatar May 26 '24 17:05 mrpotato3