在前端CSS样式开发中,隐藏页面元素是高频操作,display:none和visibility:hidden是两种最常用的隐藏方式,二者的核心差异体现在对元素渲染和布局的影响上。

核心区别总览
二者的本质差异可以通过下表快速梳理:
| 对比维度 | display:none | visibility:hidden |
|---|---|---|
| 是否占据布局空间 | 否,元素完全脱离文档流 | 是,元素保留原有占位空间 |
| 是否渲染到渲染树 | 否,元素不会被渲染 | 是,元素仅视觉隐藏 |
| 子元素继承表现 | 子元素无法覆盖隐藏状态 | 子元素可通过visibility:visible覆盖 |
| 是否支持过渡动画 | 不支持 | 支持 |
布局空间占用差异
display:none会让元素完全脱离文档流,就好像这个元素从来不存在于页面中一样,后续的元素会填补它原本的位置。而visibility:hidden只是让元素不可见,元素原本在文档流中占据的空间会保留,不会影响其他元素的位置。
我们可以通过以下代码直观验证这个差异:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<style>
.box {
width: 200px;
height: 100px;
background-color: #f0f0f0;
margin: 10px 0;
border: 1px solid #ccc;
}
.display-none {
display: none;
}
.visibility-hidden {
visibility: hidden;
}
</style>
</head>
<body>
<div class="box">第一个盒子</div>
<div class="box display-none">display:none的盒子</div>
<div class="box">第三个盒子</div>
<hr>
<div class="box">第一个盒子</div>
<div class="box visibility-hidden">visibility:hidden的盒子</div>
<div class="box">第三个盒子</div>
</body>
</html>
运行上述代码可以看到,使用display:none的盒子不会显示,且第三个盒子会紧贴第一个盒子下方;而使用visibility:hidden的盒子位置会空出一块和盒子大小一致的空白区域,第三个盒子不会上移。
渲染树处理差异
浏览器渲染页面的过程中会生成渲染树,渲染树只包含需要显示的节点。设置display:none的元素不会被加入到渲染树中,浏览器不会为其分配任何渲染资源,也不会触发该元素的重排和重绘。而设置visibility:hidden的元素会被加入到渲染树中,浏览器只是将其视觉透明度设置为0,依然会为其分配渲染资源,只是不显示在屏幕上。
这也意味着,频繁切换display:none的显示隐藏状态,会反复触发渲染树的构建,性能开销比切换visibility:hidden更大。
子元素继承规则差异
visibility属性是可继承的,父元素设置visibility:hidden后,所有子元素默认也会隐藏,但如果子元素单独设置visibility:visible,就可以覆盖父元素的隐藏规则,重新显示出来。而display:none是不可继承的,父元素设置display:none后,所有子元素都会被一同隐藏,即使子元素设置display:block也无法显示。
相关示例如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<style>
.parent {
width: 200px;
height: 150px;
background-color: #e8f4ff;
padding: 10px;
}
.child {
width: 100px;
height: 50px;
background-color: #ffcccc;
}
.parent-visibility {
visibility: hidden;
}
.child-show {
visibility: visible;
}
.parent-display {
display: none;
}
</style>
</head>
<body>
<h3>visibility:hidden继承示例</h3>
<div class="parent parent-visibility">
父元素隐藏
<div class="child child-show">子元素显示</div>
</div>
<h3>display:none继承示例</h3>
<div class="parent parent-display">
父元素隐藏
<div class="child" style="display:block">子元素无法显示</div>
</div>
</body>
</html>
动画支持差异
visibility属性支持CSS过渡动画,我们可以实现元素从隐藏到显示的渐变效果,而display:none不支持过渡动画,切换时会直接显示或隐藏,没有过渡过程。
以下是一个visibility过渡动画的示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<style>
.animate-box {
width: 200px;
height: 100px;
background-color: #cceeff;
visibility: hidden;
opacity: 0;
transition: visibility 0s, opacity 0.5s linear;
}
.animate-box.show {
visibility: visible;
opacity: 1;
}
</style>
</head>
<body>
<button onclick="document.querySelector('.animate-box').classList.toggle('show')">切换显示/隐藏</button>
<div class="animate-box">支持过渡动画的内容</div>
</body>
</html>
使用场景选择
根据上述差异,我们可以做出如下选择:
- 如果需要元素完全不占空间,且不频繁切换显示状态,优先选择
display:none - 如果需要保留元素占位空间,或者需要频繁切换显示状态、需要过渡动画效果,优先选择
visibility:hidden - 如果需要隐藏父元素但显示其中某个子元素,必须使用
visibility:hidden
display_nonevisibility_hiddenCSS前端布局修改时间:2026-06-13 10:36:23