Framer Motion嵌套motion组件失效,如何同时保留内外层动画?
解决Framer Motion嵌套motion组件的layoutId失效问题
问题原因
外层motion.div添加的layout属性会创建独立的动画上下文,阻断了内层带layoutId的motion组件的动画触发逻辑,导致切换activeSection时,红色背景的位移动画无法正常运行。
解决方案
方案1:移除外层多余的layout属性
你的外层组件只需要初始入场动画(从上方滑入+淡入),并不需要响应布局变化的layout动画,直接移除该属性即可同时保留外层初始动画和内层layoutId动画:
修改后的外层motion组件代码:
<motion.div className="fixed z-10 top-0 sm:rounded-full sm:shadow-md sm:top-5 h-[4.5rem] sm:bg-opacity-80 backdrop-blur-[0.5rem] sm:h-[3rem] w-full sm:w-[30rem] bg-slate-50 bg-opacity-70 sm:bg-white left-1/2 -translate-x-[50%]" initial={{ y: -100, x: "-50%", opacity: 0 }} animate={{ y: 0, x: "-50%", opacity: 100 }} // 移除这里的layout属性 > {/* 内部原有内容保持不变 */} </motion.div>
方案2:拆分外层motion组件(若需保留layout)
如果后续需要外层组件响应布局变化(比如动态尺寸调整),可以将外层的动画逻辑与布局内容拆分:用外层motion.div单独处理初始入场和layout动画,内层用普通div承载导航内容,这样内层的layoutId动画就不会被父级的动画上下文干扰:
<motion.div className="fixed z-10 top-0 left-1/2 -translate-x-[50%]" initial={{ y: -100, x: "-50%", opacity: 0 }} animate={{ y: 0, x: "-50%", opacity: 100 }} layout > {/* 把原className中的布局样式移到这个普通div里 */} <div className="sm:rounded-full sm:shadow-md sm:top-5 h-[4.5rem] sm:bg-opacity-80 backdrop-blur-[0.5rem] sm:h-[3rem] w-full sm:w-[30rem] bg-slate-50 bg-opacity-70 sm:bg-white"> {/* 原有的导航内容全部移到这里 */} <div className="sm:hidden w-full h-full px-8 flex items-center justify-between"> {/* ... 原有代码 ... */} </div> <nav className="hidden sm:block h-full "> {/* ... 原有代码 ... */} </nav> </div> </motion.div>
内容的提问来源于stack exchange,提问作者user25043118
相关产品推荐
相关产品推荐

