CSS transition 本身不阻塞首屏渲染,但初始状态未声明、触发时机不当、混用非合成属性、display 直接切换、图片未占位等会导致卡顿或动画失效。

CSS transition 本身不阻塞首屏渲染,但错误的写法会让浏览器在首帧“卡住”或“跳变”,造成加载生硬、白屏感、甚至布局抖动——问题不在 transition,而在它依赖的初始状态和触发时机。
transition 写在 .active 类里就失效
很多人把 transition 和目标样式都塞进激活类,比如:.box.active { transition: opacity 0.3s; opacity: 1; }。这会导致首次添加 active 时动画完全不触发,因为浏览器找不到「起始值」:元素默认没有 opacity 声明,计算出的是 opacity: 1,从 1 → 1 变化量为 0。
- 必须把
transition和**初始值**写在基础选择器中,例如:.box { opacity: 0; transition: opacity 0.3s ease; } - 目标状态只负责覆盖值:
.box.active { opacity: 1; } - 如果用 JS 添加 class,确保 DOM 已挂载、样式已计算完毕(避免在
DOMContentLoaded前操作)
用 display: none 切换直接废掉 transition
display 是不可插值属性,写了 transition: display 0.3s 完全无效。常见翻车场景:loading 面板一出现就“闪”出来,或者消失时突兀消失。
- 改用
visibility: hidden+opacity: 0组合,两者都可动画 - 过渡声明必须包含两个属性:
transition: visibility 0.2s, opacity 0.2s ease; - 激活时同时设
visibility: visible和opacity: 1,缺一不可 - 别在 JS 里直接写
el.style.display = 'block',这会绕过 CSS 中的 transition 规则
非合成属性导致整条 transition 卡顿
只要 transition 列表里混入一个非 GPU 加速属性(如 width、margin、background-color),整个过渡都会降级到 CPU 渲染,哪怕你只动 transform。
立即学习“前端免费学习笔记(深入)”;
- 只保留
transform和opacity:transition: transform 0.25s ease, opacity 0.25s ease; - 绝对不要用
transition: all 0.3s,它等于埋雷 - 父容器加了
overflow: hidden或filter: blur(1px),子元素的transform动画也会被拖垮 - 验证是否真提层:Chrome DevTools → Rendering → 勾选 “Layer borders”,绿色边框才表示 GPU 合成生效
首屏图片没预留空间,transition 被 layout 抖动拖垮
给图片加淡入动画却看到页面“跳一下”,根本原因不是 transition 慢,而是图片加载前高度为 0,加载后突然撑开容器,触发同步 layout,打断所有动画帧。
- 用
aspect-ratio或 padding-bottom 技巧提前占位:img { aspect-ratio: 16/9; object-fit: cover; } - 懒加载图片时,
src必须延迟设置(不是靠opacity掩盖),否则带宽和解析压力照旧 - 骨架屏动画也得基于固定尺寸容器,否则 shimmer 效果会被重排撕裂
真正影响首屏体验的,从来不是 transition 这个声明本身,而是它所依赖的初始状态是否明确、触发时机是否落在浏览器帧节奏里、以及是否被 layout 抖动或渲染降级悄悄瓦解。这些点不校验,再漂亮的缓动函数也救不回那一帧的卡顿。


















