display:none 彻底移出布局流,不占空间、不参与计算、屏幕阅读器不可读;visibility:hidden 保留占位、仅隐藏视觉、支持继承且子元素可恢复显示。

需要彻底移出布局流就选 display:none
当目标是让元素「不存在于视觉和布局中」,比如响应式下收起侧边栏、隐藏广告位、移除非核心图片,display:none 是唯一合理选择。它从渲染树里直接剔除节点,不占空间、不参与布局计算、后续元素自动上移,也不会被屏幕阅读器读取。
常见错误现象:@media (max-width: 768px) { .sidebar { visibility: hidden; } } 看似隐藏了侧边栏,结果主内容区被挤到右侧,留下大片空白——因为元素还在文档流里占位。
注意:display:none 具有强制性:父元素设了它,子元素无论写 display:block 还是 display:flex 都无效;它还会让 el.offsetParent 返回 null,getBoundingClientRect() 返回空集合。
要保留占位且避免布局跳动就用 visibility:hidden
当你需要元素「站原地但闭眼」,比如轮播图预加载容器、表单错误提示占位、Canvas 容器临时隐藏又恢复,visibility:hidden 才是正确解。它不触发重排(reflow),只重绘(repaint),offsetWidth、getClientRects() 等尺寸 API 依然返回有效值。
使用场景包括:
- 轮播图切换时防止容器高度塌缩导致的视觉跳动
- Tooltip 预渲染容器始终存在,仅靠
visibility控制显隐,保证定位锚点稳定 - 表单控件需隐藏但提交数据仍要保留(
display:none下<input>不会提交)
但要注意:visibility 具有继承性,父级设 hidden,子级默认也隐藏;不过子级可主动设 visibility:visible 恢复显示——这点和 display 完全不同。
别在同一个元素上混用 display 和 visibility
浏览器会同时应用两个属性,但 display:none 的优先级更高:一旦生效,visibility:hidden 就失去意义。这种混用多见于媒体查询中,比如:
@media (max-width: 768px) {
.header { display: none; }
.logo { visibility: hidden; }
}
如果 .logo 是 .header 的子元素,那它根本不会渲染,visibility 彻底失效。
更隐蔽的问题是 CSS 选择器权重干扰:.layout .sidebar { display: block; } 和 @media { .sidebar { visibility: hidden; } } 同时存在时,前者不会被后者覆盖,但两者共存会导致行为不可预测。
动画过渡和交互控制必须额外处理
display 不支持 transition,写 transition: display 0.3s 完全无效;visibility 虽然能配合 opacity 实现淡入淡出,但它本身只有 visible/hidden 两个离散值,无法插值。
关键细节:
- 想做平滑淡出,得组合
opacity+visibility+pointer-events: none+aria-hidden -
visibility:hidden默认禁用鼠标事件,但元素仍在事件捕获路径中;若要彻底屏蔽,必须加pointer-events: none -
display:none的元素根本不在事件路径里,无需额外处理
真正容易被忽略的是:表格行(<tr>)在部分浏览器中对 <code>visibility:hidden 表现异常,<tbody> 高度可能计算为 0,此时应改用 <code>display:none 或外层包裹 <div>。</div>
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











