z-index 與 Stacking Context 的關係是什麼?
z-index 是一個 CSS 屬性,用來控制元素在 z 軸(垂直於螢幕的深度方向)上的堆疊順序。而 Stacking Context(堆疊上下文) 則是瀏覽器在渲染頁面時,用來決定元素如何在 z 軸上層疊的上下文環境。簡單來說,z-index 只有在 Stacking Context 內才有效,且不同堆疊上下文之間的層次關係會影響元素的顯示順序。
什麼是 z-index?
z-index 是一個 CSS 屬性,用來指定元素在 z 軸上的堆疊順序。它的值是一個整數,數字越大,元素越靠前顯示(越靠近觀看者)。例如:
-
z-index: 10; 的元素會顯示在 z-index: 5; 的元素之上。
-
預設情況下,元素的 z-index 是 auto,表示它遵循文檔流的自然堆疊順序。
注意:
-
z-index 只對 定位元素(position: absolute, relative, fixed, 或 sticky)有效。
-
如果元素沒有設置 position,z-index 不會生效。
什麼是 Stacking Context?
Stacking Context(堆疊上下文) 是瀏覽器用來管理元素在 z 軸上的層次結構的一種機制。一個堆疊上下文就像一個「獨立的層次空間」,裡面的元素會根據它們的 z-index 值來決定堆疊順序。
什麼情況會創建一個 Stacking Context?
以下是一些常見會觸發堆疊上下文的情況:
-
根元素(
<html>
)本身是一個堆疊上下文。 -
元素設置了 position: absolute 或 position: relative,並且有明確的 z-index 值(非 auto)。
-
元素設置了 position: fixed 或 position: sticky。
-
元素使用了 CSS 屬性,例如:
-
opacity 小於 1(例如 opacity: 0.5)。
-
transform(例如 transform: translate(10px, 10px))。
-
filter(例如 filter: blur(5px))。
-
mix-blend-mode(非 normal)。
-
isolation: isolate。
-
-
元素是 Flexbox 或 Grid 容器的子元素,且有 z-index 值(非 auto)。
一旦一個元素創建了堆疊上下文,它的子元素會在這個上下文中進行層次排序,且無法影響外部其他堆疊上下文的層次。
z-index 與 Stacking Context 的關係
z-index 的作用範圍受限於它所在的 Stacking Context。這意味著:
-
在同一個堆疊上下文中,z-index 決定元素的堆疊順序。
-
如果兩個元素位於不同的堆疊上下文中,子上下文中的 z-index 無法超越父上下文的層次。
這就像是不同「樓層」之間的關係:每個堆疊上下文是一個獨立的「樓層」,樓層內的元素可以根據 z-index 調整順序,但樓層之間的順序由父層的堆疊上下文決定。
範例:z-index 在 Stacking Context 中的行為
以下是一個具體的 HTML 和 CSS 範例,幫助你理解 z-index 和堆疊上下文的關係,並可以直接複製到你的專案中測試。
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8" />
<title>z-index 與 Stacking Context 範例</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div class="container">
<div class="box box1">方塊 1 (z-index: 10)</div>
<div class="box box2">方塊 2 (z-index: 5)</div>
<div class="sub-container">
<div class="box box3">方塊 3 (z-index: 100)</div>
</div>
</div>
</body>
</html>
CSS (styles.css)
.container {
position: relative; /* 創建一個堆疊上下文 */
z-index: 1;
width: 400px;
height: 400px;
background-color: #f0f0f0;
}
.sub-container {
position: relative; /* 創建另一個堆疊上下文 */
z-index: 2; /* 子容器比父容器的 z-index 高 */
top: 100px;
left: 100px;
width: 200px;
height: 200px;
background-color: rgba(0, 0, 0, 0.1);
}
.box {
width: 100px;
height: 100px;
position: absolute;
}
.box1 {
background-color: red;
z-index: 10; /* 在 container 的堆疊上下文中 */
top: 50px;
left: 50px;
}
.box2 {
background-color: blue;
z-index: 5; /* 在 container 的堆疊上下文中,比 box1 低 */
top: 80px;
left: 80px;
}
.box3 {
background-color: green;
z-index: 100; /* 在 sub-container 的堆疊上下文中 */
top: 20px;
left: 20px;
}
如果看不到 codepen playground,請重新整理頁面
See the Pen 你的 CodePen 標題 by Retsnom on CodePen.
操作步驟
你會看到:
-
方塊 1(紅色) 在 方塊 2(藍色) 之上,因為它們在同一個堆疊上下文(.container),且 z-index: 10 比 z-index: 5 高。
-
即使 方塊 3 的 z-index: 100 很高,它仍然受限於 .sub-container 的堆疊上下文,不會影響 .container 內的元素。
為什麼會這樣?
-
.container 和 .sub-container 分別創建了兩個獨立的堆疊上下文。
-
.sub-container 的 z-index: 2 使它的整個堆疊上下文顯示在 .container(z-index: 1)之上。
-
在 .sub-container 內,方塊 3 的 z-index: 100 只影響它在自己的堆疊上下文中的順序,無法影響外部的 方塊 1 或 方塊 2。
常見問題與解決方法
-
問題:為什麼我的 z-index 設得很高卻沒效果?
-
原因:你的元素可能位於一個較低層級的堆疊上下文中,無法超越父層的限制。
-
解決方法:檢查父元素是否創建了堆疊上下文(例如設置了 position 和 z-index、或 opacity 小於 1)。如果需要,將元素移到更高層級的堆疊上下文中,或調整父元素的 z-index。
-
-
問題:如何檢查堆疊上下文?
-
使用瀏覽器的開發者工具(F12),檢查元素的 CSS 屬性,確認是否有 position、z-index 或其他觸發堆疊上下文的屬性。
-
逐步檢查父元素的層次結構,找出哪個元素創建了堆疊上下文。
-
-
問題:如何避免不必要的堆疊上下文?
-
避免在不需要的情況下使用 opacity、transform 等屬性。
-
如果只需要定位,設置 position: relative 並避免指定 z-index,以免創建新的堆疊上下文。
-
實用建議
-
保持簡單:除非必要,盡量減少創建堆疊上下文的屬性,這樣可以讓層次管理更簡單。
-
分層規劃:在設計頁面時,先規劃好哪些元素需要獨立的堆疊上下文,並為它們分配適當的 z-index 值。
-
測試與除錯:在複雜的頁面中,使用瀏覽器開發者工具檢查元素的層次,並逐步調整 z-index 和堆疊上下文。
總結
-
z-index 決定元素在同一個堆疊上下文中的層次順序。
-
Stacking Context 是一個獨立的層次環境,限制了 z-index 的作用範圍。
-
不同堆疊上下文之間的層次由父元素的 z-index 決定,子元素無法超越父層的限制。
-
透過範例中的程式碼,你可以實際操作並觀察 z-index 和堆疊上下文的行為。