CSS z-index

z-index 屬性用來控制元素的堆疊順序,決定當元素重疊時哪個顯示在上面。

基本用法

.front {
  z-index: 10;     /* 較高的值在上層 */
}

.back {
  z-index: 1;      /* 較低的值在下層 */
}

數值越大,元素越在上層。

使用條件

z-index 只對「定位元素」有效,也就是 position 不是 static 的元素:

/* 無效:static 元素 */
.box {
  z-index: 100;    /* 不會生效 */
}

/* 有效:有定位的元素 */
.box {
  position: relative;
  z-index: 100;    /* 會生效 */
}

z-index 值

.box {
  z-index: auto;    /* 預設值,等同於 0 */
  z-index: 0;
  z-index: 1;
  z-index: 100;
  z-index: 9999;
  z-index: -1;      /* 可以是負值 */
}

堆疊上下文 (Stacking Context)

堆疊上下文是一個三維的概念,決定了元素如何在 z 軸上堆疊。

建立堆疊上下文的條件

以下情況會建立新的堆疊上下文:

  • 根元素 (<html>)
  • position: absoluterelativez-index 不是 auto
  • position: fixedsticky
  • opacity 小於 1
  • transformfilterperspective 不是 none
  • isolation: isolate
  • Flexbox 或 Grid 的子元素且 z-index 不是 auto

堆疊上下文的影響

子元素的 z-index 只在其堆疊上下文內比較:

.parent-a {
  position: relative;
  z-index: 1;
}

.child-a {
  position: absolute;
  z-index: 9999;    /* 雖然很高,但還是在 parent-a 的堆疊上下文內 */
}

.parent-b {
  position: relative;
  z-index: 2;       /* parent-b 會在 parent-a 上面 */
}

即使 .child-a 的 z-index 是 9999,它仍然會被 .parent-b 遮住,因為 .parent-a 的 z-index 只有 1。

常用 z-index 值規劃

建議為專案建立一套 z-index 規範:

:root {
  --z-dropdown: 100;
  --z-sticky: 200;
  --z-fixed: 300;
  --z-modal-backdrop: 400;
  --z-modal: 500;
  --z-popover: 600;
  --z-tooltip: 700;
}

.dropdown-menu {
  z-index: var(--z-dropdown);
}

.navbar {
  z-index: var(--z-fixed);
}

.modal {
  z-index: var(--z-modal);
}

實用範例

覆蓋層和彈窗

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 100;
}

.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 101;    /* 比 overlay 高 */
}

下拉選單

.dropdown {
  position: relative;
}

.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 100;
}

固定導航列在下拉選單之下

.navbar {
  position: fixed;
  z-index: 50;
}

.dropdown-menu {
  z-index: 100;    /* 比 navbar 高,可以蓋過它 */
}

負 z-index

負值可以讓元素顯示在其他內容後面:

.background-decoration {
  position: absolute;
  z-index: -1;     /* 在內容後面 */
}

常見問題

z-index 沒有作用

  1. 沒有設定 position:確認元素有 position: relative/absolute/fixed/sticky
  2. 堆疊上下文:父元素可能建立了堆疊上下文,限制了 z-index 的作用範圍
  3. 值不夠大:嘗試增加 z-index 值

避免 z-index 戰爭

  • 建立統一的 z-index 規範
  • 使用 CSS 變數管理 z-index
  • 避免使用過大的數值(如 999999)
  • 考慮使用 isolation: isolate 來隔離堆疊上下文
/* 使用 isolation 建立獨立的堆疊上下文 */
.component {
  isolation: isolate;
}

預設堆疊順序

沒有 z-index 時,元素的堆疊順序由下到上為:

  1. 根元素的背景和邊框
  2. 非定位的區塊元素(按 HTML 順序)
  3. 浮動元素
  4. 非定位的行內元素
  5. 定位元素(按 HTML 順序)