You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用framer-motion实现子元素增减时div尺寸平滑过渡动画?

问题描述

移除选项时容器尺寸突然跳转的效果

当选择“全部”选项移除所有已选项目时,包裹这些选项的div会突然跳转收缩,我希望实现平滑的收缩动画,避免选项下方的分隔线越过“mindegy”选项。

以下是当前的部分代码(已选选项的渲染逻辑):

<AnimatePresence>
        {selectedOptions.map((option) => (
          <motion.div
            layout
            initial={{ opacity: 0, scale: 0}}
            animate={{ opacity: 1, scale: 1 }}
            exit={{ opacity: 0, scale: 0 }}
            key={option.value}
            className="flex items-center  justify-center bg-slate-300 max-w-36 text-sm m-2  border border-slate-300 rounded-2xl">
            <div className="p-1 ml-2">{option.text}</div>
            <X
              onClick={() => updateSelection(option, false)}
              className="ml-1 mr-1 cursor-pointer hover:text-gray-500 text-zinc-600"
              size={16}
            />
          </motion.div>
        ))}
  </AnimatePresence>
解决方案

问题核心是父容器没有跟随子元素的退场动画做平滑尺寸过渡——当所有子元素同时执行exit动画时,AnimatePresence默认会在子元素动画结束后立即移除DOM,父容器直接跳转到空状态尺寸,导致突兀跳转。

你可以通过两步修复:

  1. 给父容器添加motion能力
    将包裹<AnimatePresence>的普通div改成<motion.div>,并加上layout属性。这样父容器会自动感知子元素的尺寸变化,生成平滑的收缩动画。

  2. 设置AnimatePresence的mode为"wait"
    让AnimatePresence等待所有子元素的exit动画完成后再移除DOM,确保父容器有足够时间完成尺寸过渡。

修改后的完整代码示例:

{/* 把父容器改成motion.div,添加layout属性 */}
<motion.div layout className="flex flex-wrap">
  <AnimatePresence mode="wait">
    {selectedOptions.map((option) => (
      <motion.div
        layout
        initial={{ opacity: 0, scale: 0}}
        animate={{ opacity: 1, scale: 1 }}
        exit={{ opacity: 0, scale: 0, transition: { duration: 0.3 } }} {/* 统一动画时长,和父容器节奏匹配 */}
        key={option.value}
        className="flex items-center justify-center bg-slate-300 max-w-36 text-sm m-2 border border-slate-300 rounded-2xl">
        <div className="p-1 ml-2">{option.text}</div>
        <X
          onClick={() => updateSelection(option, false)}
          className="ml-1 mr-1 cursor-pointer hover:text-gray-500 text-zinc-600"
          size={16}
        />
      </motion.div>
    ))}
  </AnimatePresence>
</motion.div>

额外提示:

  • 给子元素的exit动画设置统一的transition.duration,能让子元素退场和父容器收缩的节奏更协调。
  • 尽量保持父容器的布局样式简洁,避免复杂的padding/margin干扰layout动画的尺寸计算。

内容的提问来源于stack exchange,提问作者J.Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:25:07