display: none 使元素彻底退出布局且不被读屏器读取,但无法过渡动画;opacity: 0 支持淡入淡出但保留占位与交互,需配合 pointer-events: none 禁用点击;visibility: hidden 介于二者之间,仅视觉隐藏、不触发回流但无渐变效果。

display: none 会导致元素完全消失,但无法做淡入淡出动画
如果你需要让元素彻底退出布局、不占空间、不被读屏器读取,display: none 是唯一选择。但它有个硬伤:transition 对它无效——因为 display 是离散值(block/none 等),浏览器无法插值过渡。
常见错误是这样写:
.fade-out { display: none; transition: display 0.3s ease; }
结果毫无动画效果,元素直接闪退。真正可行的做法是:先用 opacity: 0 + transition 实现淡出,再在动画结束时用 JavaScript 切换 display: none 来释放空间。
- 适用场景:权限控制菜单、表单校验失败提示、后台管理中按角色隐藏的模块
- 副作用:触发回流(reflow),频繁切换会卡顿
- 无障碍影响:读屏器完全跳过该元素,适合“永久性隐藏”或“当前无意义内容”
opacity: 0 保留布局和交互能力,适合做过渡动画
opacity: 0 不改变文档流,元素仍占位、仍可接收点击/键盘焦点、仍被读屏器读取。这是它和 display: none 最本质的区别。
典型误用是把它当“安全隐藏”——比如把按钮设为 opacity: 0 后以为用户点不到,结果测试发现还能触发 click 事件,甚至 tab 键能聚焦过去。
- 必须配合
pointer-events: none和user-select: none才能禁用交互 - 子元素继承透明度,
opacity: 1在子元素上无法“抵消”父级的opacity: 0 - 性能友好:只触发重绘(repaint)或 GPU composite,不引发回流
- 动画流畅:支持
transition和@keyframes,是实现 fade-in/out 的事实标准
别忽略 visibility: hidden 这个中间选项
很多人直接在 display: none 和 opacity: 0 之间二选一,却忘了 visibility: hidden 是更轻量的“视觉隐藏”方案。
它不占空间?错。它不可交互?对。它支持过渡?部分支持——但只能从 visible → hidden 或反过来,且没有渐变效果(“大于 0 就显示”,所以过渡看起来是突变)。
- 优势:切换开销最小,只重绘,不回流;子元素可用
visibility: visible单独显示 - 劣势:读屏器仍会读取内容(不像
display: none),也不像opacity: 0支持平滑动画 - 适合场景:临时隐藏 tooltip、下拉菜单收起状态、表格行批量隐藏(需保持行高一致)
复杂点在于混合使用和时机控制
真实项目里几乎不会只用单一方式。比如一个 modal 关闭动效:先 opacity: 0 + transform: scale(0.95) 动画,动画结束瞬间加 display: none;打开时则反向:先 display: block,再 opacity: 0 → 1 + scale 动画。
容易被忽略的是事件监听和焦点管理——display: none 元素上的事件监听器自动失效,而 opacity: 0 元素的事件照常触发,但用户看不见响应反馈,可能误操作。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











