motion
motion copied to clipboard
[BUG] Stagger animation does not occur when children has a "whileHover" animation
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:
- Go to the codesandbox ☝️
- Notice the staggered animation occurs as expected 👍
- Uncomment the
whileHoverstatement and refresh - 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
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
Thank you @KirdesMF that's a good workaround!
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
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.
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
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 .
Any updates on this issue?
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.
For me it isn't working either. Using in conjunction with whileInView
Yup not working with whileInView
Any updates on this? It's not just the whileInView that is broken.
Variants in combination with useAnimation() also doesn't work.
+1