opacity渐显最稳,需显式设初始值0并避免display:none;滚动渐显用IntersectionObserver配rootMargin;iframe需轮询readyState;多文本淡入用calc()动态delay。

transition + opacity 是最稳的渐显方案
直接给元素加 opacity: 0 初始值,再用 transition: opacity 0.4s ease 控制变化,是最轻量、兼容性最好、且不触发重排的方式。它不依赖 JS,也不需要监听事件,适合按钮悬停、模态框入场等确定性场景。
常见错误是只在 :hover 或 class 里写 opacity: 1,而没在基础样式中声明 opacity: 0 —— 这会导致 transition 不生效,动画直接跳变。
- 必须显式设置初始
opacity值(哪怕为 0),否则浏览器无“起始状态”可插值 - 避免和
display: none混用:display不可过渡,一设即消失,transition 彻底失效 - 移动端要注意 iOS Safari 对
opacity动画的渲染抖动,加will-change: opacity可缓解
滚动进入视口才渐显?用 IntersectionObserver
用户还没看到就提前动画,体验差;等滚动到位置再触发,才是真正的“渐显”。IntersectionObserver 是现代标准解法,比手动监听 scroll 事件更高效、不卡顿,且天然支持移动端。
别用 scroll + getBoundingClientRect() 手动判断:频繁触发重排,iOS 上容易掉帧,且临界点判断不准,常出现“刚露头就动完”或“已过半才开始”。
立即学习“前端免费学习笔记(深入)”;
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 监听
isIntersecting为true时添加.visible类,CSS 里定义opacity和transform过渡 - 配
rootMargin: '50px'提前触发,避免快速滚动时白屏 - 对图片等资源,需额外检查
img.complete && img.naturalWidth > 0,防止骨架占位未退场就动画
iframe 加载完成再渐显?别信 onload
iframe.onload 在跨域或缓存场景下不可靠:可能早于 contentDocument.readyState === 'complete' 触发,导致内容未真正就绪就淡入,露出白底或错位布局。
正确做法是用 wrapper 容器控制显隐,并主动轮询 iframe 内部文档状态:
- 初始设 wrapper
opacity: 0,iframe 本身visibility: hidden防闪烁 - 用
setInterval检查iframe.contentDocument?.readyState === 'complete' - 超时(如 5s)后强制显示,避免无限等待
多个文本依次淡入?animation-delay 要算准
用 CSS @keyframes 配合 animation-delay 实现队列效果,比 JS 循环 setTimeout 更稳定,也避免重排压力。但 delay 值不是拍脑袋定的——它得和动画持续时间、缓动函数配合,否则首尾衔接生硬。
比如每个动画 0.6s,ease-out 下实际加速段短、减速段长,若简单设 animation-delay: 0.6s,第二项会等第一项完全停住才启动,节奏拖沓。
- 推荐用
animation-delay: calc(0.4s * var(--index)),把延迟控制在动画主体区间内 - 用 CSS 自定义属性传递序号,比写死多个 class 更易维护
- 注意:IE 不支持
calc()在 animation-delay 中使用,需提供降级 fallback
关键点始终落在“状态是否真实就绪”上——opacity 可以过渡,但前提是元素已挂载、尺寸已确定、内容已加载完毕。很多渐显失败,不是代码写错了,而是动画被提前释放了。


















