直接给li加transition无动画,因新dom节点无初始样式状态;需先插入、再强制重排(如读offsetheight)、最后加过渡类;animation方案更可靠,须配animation-fill-mode:forwards且避免display:none。

为什么直接给 li 加 transition: all 0.3s 没动画
因为新插入的 DOM 节点没有“初始样式状态”,浏览器跳过过渡,直接渲染最终样式。CSS transition 只响应已存在元素的属性变化,不处理“从无到有”的过程。常见表现是:元素一闪就出现,毫无滑入或淡入效果。
必须手动触发重排(reflow)才能启动过渡
核心三步缺一不可,且顺序和时机不能错:
- 用
appendChild()或insertAdjacentElement()插入li - 立即读取一个布局相关属性,例如
el.offsetHeight或getComputedStyle(el).height—— 这会强制浏览器同步计算并记住当前样式(如opacity: 0、transform: translateY(20px)) - 紧接着添加目标类名,例如
li.classList.add('slide-in'),该类需含transition: opacity 0.3s, transform 0.3s
任何异步延迟(比如 setTimeout)都会让浏览器合并渲染,导致动画起点丢失。
animation 方案比 transition 更适合初始化入场
用 @keyframes + animation 更可靠,尤其适合批量插入场景:
- 先在 CSS 中定义初始态:
li { opacity: 0; transform: translateY(20px); } - 动画类必须带
animation-fill-mode: forwards,否则动画播完会闪回opacity: 0 - JS 插入后立刻加类:
li.classList.add('animate-in'),类中声明animation: fadeInUp 0.4s ease-out forwards - 避免用
display: none控制显隐——它会中断渲染流程,动画无法触发;改用opacity: 0; visibility: hidden;或transform配合
注意:每个 li 必须单独加类,否则所有项会同时开始动画,失去阶梯感。
Flex 容器里用 flex-basis 做主轴动画的坑
别写 flex-basis: auto + transition: flex-basis —— 浏览器无法插值 auto,动画静默失效,不报错也不动。
- 插入前先读真实值:
getComputedStyle(item).flexBasis(通常是"0px"或具体像素) - 插入后立即设
item.style.flexBasis = '0px'; item.style.opacity = '0' - 立刻触发重排:
item.offsetHeight - 再设目标值:
item.style.flexBasis = '200px'; item.style.opacity = '1',并确保已有transition: flex-basis 0.25s, opacity 0.25s - 删除时慎用
flex-basis: 0直接收起:容易因 DOM 移除过早而截断动画;建议配合max-height或transform: scaleY(0)并监听transitionend再移除
真正容易被忽略的是:flex-basis 动画只影响主轴尺寸,若列表项高度差异大,它无法控制垂直方向收放节奏——这时候得靠组合方案,不是单靠一个属性能兜底的。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











