關於display:none與visibility:hidden
分析和研究兩者css屬性的差異和特性
在前端開發中,display:none
和 visibility:hidden
是兩個常用的 CSS 屬性,用來控制元素的顯示和隱藏。雖然它們都能達到隱藏元素的效果,但在應用場景、性能和影響上卻有顯著差異。本文將深入探討這兩個屬性,並對它們的優勢和劣勢進行詳細比較。
TLDR
display:none
完全移除元素,不佔用空間,適合需要暫時不顯示內容的情況,但會觸發Reflowvisibility:hidden
隱藏元素但保留空間,適合需要保持布局不變的情況,性能開銷較低,但會保留事件響應問題。- 兩者都會參與構建DOM Tree
一、display:none
與 visibility:hidden
的基本概念
1.1 display:none
display:none
是一個用來完全移除元素的 CSS 屬性。當元素被設置為 display:none
時,它不僅從視覺上消失,還會完全從 DOM 的渲染樹中移除,不佔用任何空間,但仍有參與構建DOM Tree (使用getElementById去check)。
Example:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Example</title>
<style>
.hidden {
display: none;
}
</style>
</head>
<body>
<div class="visible">可見元素</div>
<div id="hidden-element" class="hidden">隱藏元素</div>
<script>
var hiddenElement = document.getElementById('hidden-element');
console.log(hiddenElement);
</script>
</body>
</html>
1.2 visibility:hidden
visibility:hidden
是一個用來隱藏元素的CSS屬性。但與 display:none
不同,visibility:hidden
只是讓元素不可見,元素依然佔據原本的位置和空間。並且也參與構建DOM Tree。
Example:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>visibility:hidden 示例</title>
<style>
.hidden {
visibility: hidden;
}
</style>
</head>
<body>
<div class="visible">可見元素</div>
<div id="hidden-element" class="hidden">隱藏元素,佔據空間</div>
<script>
var hiddenElement = document.getElementById('hidden-element');
console.log(hiddenElement);
</script>
</body>
</html>
二、display:none
與 visibility:hidden
的區別
這裡以三個常見的隱藏方法去做比較
-
display:none
:- DOM結構:瀏覽器不會渲染
display
屬性為none
的元素,但仍參與DOM Tree構建,不佔據空間。 - 事件監聽:無法進行 DOM 事件監聽,因為元素從渲染樹中移除。
- 性能:動態改變此屬性時會引起 Reflow,性能開銷較大。
- 繼承:不會被子元素繼承,因為子元素也不會被渲染。
- DOM結構:瀏覽器不會渲染
-
visibility:hidden
:- DOM結構:元素被隱藏,但會被渲染,不會消失,並佔據空間。
- 事件監聽:無法進行 DOM 事件監聽,因為元素不可見。
- 性能:動態改變此屬性時會引起 Repaint,性能開銷較低。
- 繼承:會被子元素繼承,子元素可以通過設置
visibility: visible;
來取消隱藏。
-
opacity: 0
:- DOM結構:透明度為 0%,元素隱藏,但佔據空間。
- 事件監聽:可以進行 DOM 事件監聽,因為元素仍在渲染樹中。
- 性能:提升為合成層,不會觸發 Repaint,性能較高。
- 繼承:會被子元素繼承,但子元素無法通過
opacity: 1
來取消隱藏。
三、優勢與劣勢
3.1 display:none
的優勢與劣勢
優勢:
- 完全移除元素: 可以完全移除元素,適合用於需要暫時不顯示的內容,比如彈出框、選單等。
- 不佔用空間: 因為元素完全從布局中移除,所以不會影響其他元素的布局,適合用於需要動態改變布局的場景。
- 提升性能: 在某些情況下,
display:none
可能會提升性能,因為瀏覽器不需要為隱藏的元素計算樣式和佈局。
劣勢:
- Reflow 開銷大: 設置或移除
display:none
會觸發 Reflow,性能開銷較大。 - 不可用於過渡效果: 無法與 CSS 過渡效果一起使用,因為元素會立即從 DOM 中移除。
3.2 visibility:hidden
的優勢與劣勢
優勢:
- 保留空間: 保留了元素在頁面上的空間,適合用於需要保持布局不變的情況,比如表格中的單元格隱藏。
- 低性能開銷: 只會觸發 Repaint,性能開銷較低,適合頻繁顯示或隱藏元素的場景。
- 可用於過渡效果: 可以與 CSS 過渡效果一起使用,適合需要淡入淡出的場景。
劣勢:
- 仍然佔用空間: 元素仍然佔用空間,可能會影響布局和其他元素的顯示。
- 事件響應問題: 雖然元素不可見,但仍然存在於 DOM 中,可能會導致一些意想不到的事件響應問題。
五、常見案例
5.1 Example: 動態隱藏和顯示導航菜單
在某些情況下,我們需要動態隱藏和顯示導航菜單。在這個案例中,我們可以使用 display:none
和 visibility:hidden
來實現不同的效果。
使用 display:none
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>動態隱藏和顯示導航菜單</title>
<style>
.menu {
display: none;
}
.menu.active {
display: block;
}
</style>
</head>
<body>
<button onclick="toggleMenu()">切換菜單</button>
<div id="menu" class="menu">
<ul>
<li>首頁</li>
<li>關於我們</li>
<li>聯絡我們</li>
</ul>
</div>
<script>
function toggleMenu() {
const menu = document.getElementById('menu');
menu.classList.toggle('active');
}
</script>
</body>
</html>
使用 visibility:hidden
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>動態隱藏和顯示導航菜單</title>
<style>
.menu {
visibility: hidden;
}
.menu.active {
visibility: visible;
}
</style>
</head>
<body>
<button onclick="toggleMenu()">切換菜單</button>
<div id="menu" class="menu">
<ul>
<li>首頁</li>
<li>關於我們</li>
<li>聯絡我們</li>
</ul>
</div>
<script>
function toggleMenu() {
const menu = document.getElementById('menu');
menu.classList.toggle('active');
}
</script>
</body>
</html>
5.2 Example: 表格中隱藏列
在處理表格時,我們可能需要隱藏某些列,但希望其他列的位置不變。在這種情況下,visibility:hidden
是一個更好的選擇。
使用 visibility:hidden
隱藏表格列
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>隱藏表格列</title>
<style>
.hidden {
visibility: hidden;
}
</style>
</head>
<body>
<table border="1">
<tr>
<th>Name</th>
<th class="hidden">Age</th>
<th>Gender</th>
</tr>
<tr>
<td>Alice</td>
<td class="hidden">28</td>
<td>Female</td>
</tr>
<tr>
<td>Bob</td>
<td class="hidden">34</td>
<td>Male</td>
</tr>
</table>
</body>
</html>
六、總結
display:none
和 visibility:hidden
是兩個強大的工具,它們各自有著不同的應用場景和優勢。在選擇使用哪一個屬性時,應該根據具體需求和性能考量來做出決定。