Skip to main content

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?

以下是一些常見會觸發堆疊上下文的情況:

  1. 根元素<html>)本身是一個堆疊上下文。

  2. 元素設置了 position: absolute 或 position: relative,並且有明確的 z-index 值(非 auto)。

  3. 元素設置了 position: fixed 或 position: sticky。

  4. 元素使用了 CSS 屬性,例如:

    • opacity 小於 1(例如 opacity: 0.5)。

    • transform(例如 transform: translate(10px, 10px))。

    • filter(例如 filter: blur(5px))。

    • mix-blend-mode(非 normal)。

    • isolation: isolate。

  5. 元素是 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;
}
My tip

如果看不到 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

常見問題與解決方法

  1. 問題:為什麼我的 z-index 設得很高卻沒效果?

    • 原因:你的元素可能位於一個較低層級的堆疊上下文中,無法超越父層的限制。

    • 解決方法:檢查父元素是否創建了堆疊上下文(例如設置了 position 和 z-index、或 opacity 小於 1)。如果需要,將元素移到更高層級的堆疊上下文中,或調整父元素的 z-index。

  2. 問題:如何檢查堆疊上下文?

    • 使用瀏覽器的開發者工具(F12),檢查元素的 CSS 屬性,確認是否有 position、z-index 或其他觸發堆疊上下文的屬性。

    • 逐步檢查父元素的層次結構,找出哪個元素創建了堆疊上下文。

  3. 問題:如何避免不必要的堆疊上下文?

    • 避免在不需要的情況下使用 opacity、transform 等屬性。

    • 如果只需要定位,設置 position: relative 並避免指定 z-index,以免創建新的堆疊上下文。

實用建議

  • 保持簡單:除非必要,盡量減少創建堆疊上下文的屬性,這樣可以讓層次管理更簡單。

  • 分層規劃:在設計頁面時,先規劃好哪些元素需要獨立的堆疊上下文,並為它們分配適當的 z-index 值。

  • 測試與除錯:在複雜的頁面中,使用瀏覽器開發者工具檢查元素的層次,並逐步調整 z-index 和堆疊上下文。

總結

  • z-index 決定元素在同一個堆疊上下文中的層次順序。

  • Stacking Context 是一個獨立的層次環境,限制了 z-index 的作用範圍。

  • 不同堆疊上下文之間的層次由父元素的 z-index 決定,子元素無法超越父層的限制。

  • 透過範例中的程式碼,你可以實際操作並觀察 z-index 和堆疊上下文的行為。