opacity淡入本质是0→1渐变,需加forwards防闪回,禁用from避免跳帧;visibility/display不可替代因交互与布局行为不同;触发方式选transition(用户操作)或animation(自动/复杂动效)。

用 @keyframes + animation 控制 opacity 淡入
淡入本质是让元素从透明(opacity: 0)渐变到不透明(opacity: 1),CSS 原生支持,无需 JS。关键不是“能不能”,而是动画是否立即触发、是否可复用、是否影响布局。
最简可行写法:
div {
opacity: 0;
animation: fadeIn 0.3s ease-in forwards;
}
@keyframes fadeIn {
to { opacity: 1; }
}
-
forwards必须加,否则动画一结束就闪回opacity: 0 - 别用
from { opacity: 0; }—— 如果元素初始没设opacity: 0,动画可能跳帧或不触发 -
ease-in比linear更自然,但若需和其它动效节奏统一,优先用项目已定义的缓动函数(如cubic-bezier(0.25, 0.46, 0.45, 0.94))
为什么 visibility 和 display 不能替代 opacity
opacity 只影响视觉透明度,元素仍占位、仍响应事件;而 visibility: hidden 虽保留占位但不响应交互,display: none 则彻底脱离文档流——这三者行为完全不同,混用会导致点击失效、布局跳动、焦点丢失。
- 淡入后要能点击?必须用
opacity,并确保pointer-events: auto(默认值,但显式写上更稳妥) - 想淡入+同时隐藏滚动条或禁用交互?得额外控制
pointer-events或overflow,不能指望opacity附带这些效果 - 用
display: none配合animation?无效——display不是可动画属性,浏览器会直接跳变
transition 和 animation 选哪个?
如果淡入由用户操作触发(比如 hover、JS 控制 class 切换),transition 更轻量、更易维护;如果是页面加载时自动淡入,或需要循环/延迟/多阶段变化,必须用 animation。
常见误用:
.card {
opacity: 0;
transition: opacity 0.3s;
}
.card.show { opacity: 1; }
- 这个写法没问题,但前提是
.show是通过 JS 动态添加的——如果 HTML 里已经写了class="card show",那过渡不会触发(没有“变化”发生) -
transition不支持delay启动,想首屏加载 200ms 后再淡入?只能切到animation或用setTimeout延迟加 class -
transition的性能略优于animation(尤其大量元素同时动),但差距在现代浏览器里几乎不可测
移动端 Safari 和低版本 Chrome 的兼容性注意点
所有主流浏览器都支持 opacity 动画,但有两个真实存在的坑:
- iOS Safari 15.4 之前,
opacity动画在position: fixed元素上可能出现闪烁,解决方案是加transform: translateZ(0)强制硬件加速 - Android WebView(尤其旧版)对
animation-fill-mode: forwards支持不稳定,保险起见,JS 添加类后,再用getComputedStyle(el).opacity校验最终值是否为"1" - 别用
opacity: 0.01当“完全透明”——它依然会触发渲染和合成层,真正要隐藏又保留结构,还是得靠visibility: hidden单独控制
动画本身很简单,难的是判断该不该动、动完还留不留交互能力、以及在各种边界设备上是否真如预期那样淡出来。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











