iT邦幫忙

2022 iThome 鐵人賽

DAY 29
2

情境

z-index 可以幫助我們決定當元素重疊的時候,誰在上面,誰在下面。

那我們該如何使用 z-index 呢?首先,因為 z-index 只用於「重疊」的物件,白話來講,如果物件、元素彼此之間都沒有重疊,那也就沒有必要決定誰在上面、誰在下面了嘛!

重疊,通常都是透過定位相關的屬性來實做的,例如 position: absolute; 就是一個例子。

.box {
  width: 100px;
  height: 100px;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
}

.red {
  /* 暫不設置 */
}

.purple {
  position: absolute;
  left: 80px;
  top: 40px;
}

.orange {
  position: absolute;
  left: 160px;
  top: 80px;
}
<div class="box red" style="background: red;">A</div>
<div class="box purple" style="background: purple;">B</div>
<div class="box orange" style="background: orange;">C</div>

那假設,我們希望 B 在最上層,我們就能夠對他設置 z-index,此時就能夠讓 B 在 C 上層:

.purple {
  position: absolute;
  left: 80px;
  top: 40px;
  z-index: 1;
}

在上述的情境之下,我們就是看 B 和 C 誰的 z-index 比較大,誰就會在上面。這就是 z-index 最基本的概念。

你能看見多遠的未來呢?

沒有設 position

延續上述的例子,剛剛一直都是 B 和 C 在比大小,今天 A 不高興了,他也想要在最上面,所以我們會很直覺得想要對他設置 z-index

.red {
  z-index: 3;
}

.purple {
  position: absolute;
  left: 80px;
  top: 40px;
  z-index: 2;
}

.orange {
  position: absolute;
  left: 160px;
  top: 80px;
  z-index: 1;
}

結果,我們很吃驚的發現,居然還是 B 在最上面!!!?

這時候我就不高興了,一怒之下,我就讓 A 的 z-index 變成超級無敵大:

.red {
  z-index: 99999;
}

.purple {
  position: absolute;
  left: 80px;
  top: 40px;
  z-index: 2;
}

.orange {
  position: absolute;
  left: 160px;
  top: 80px;
  z-index: 1;
}

結果,不管你把 A 的 z-index 設多大,還是無法改變現狀。

到底為什麼會這樣呢?原因是,A 並沒有設定 position,因此 z-index 就不會有作用。

回想一下當初,我們為了製造「重疊」的情境,我們讓 B 和 C 都設置 position: absolute;,但是因為起初 A 並沒有要疊在誰上面,所以我們就沒有對他設置 position 了。

但是今天我們只要為 A 設置 position,就能夠達到我們希望的效果,而且我們還不需要對 z-index 胡亂設置:

.red {
  position: relative;
  z-index: 3;
}

.purple {
  position: absolute;
  left: 80px;
  top: 40px;
  z-index: 2;
}

.orange {
  position: absolute;
  left: 160px;
  top: 80px;
  z-index: 1;
}

如上圖,他就會按照順序乖乖排好,該在上面就在上面,該在下面就在下面。

父元素的順位

z-index 是一個還蠻社會化的屬性,因為他很「靠爸」。嗯?你怎麼罵髒話?不不不,我說的是,真的靠「爸」。

各位有沒有在面試的時候,或是升學的時候,有一些難以理解的經驗?明明我能力比較好,為什麼最後錄取的卻是別人?被刷下來的總是我?結果發現,原來是別人的爸爸比較厲害。

z-index 也有這種特性,簡單來說就是當父元素的順位不一樣的時候會以父元素的順位為優先。

我們來看下面範例,有一個富爸爸 z-index: 2; 跟一個努力的爸爸 z-index: 1;,努力的爸爸雖然輸給了富爸爸,但是他有一個天才的兒子 z-index: 9999,智力體能都達到了天花板。最後卻發現,居然輸給了富爸爸的凡人兒子 z-index: 1;

.very-rich {
  z-index: 2;
}

.work-hard {
  z-index: 1;
}

.general {
  z-index: 1;
}

.genius {
  z-index: 9999;
}
<div class="container">
  <div class="parent very-rich">
    Parent<br>z-index: 2
    <div class="children general">Children<br>z-index: 1</div>
  </div>

  <div class="parent work-hard">
    Parent<br>z-index: 1
    <div class="children genius">Children<br>z-index: 9999</div>
  </div>
</div>

是不是覺得 z-index 真的有點殘忍?難道努力跟天份都是沒有用的嗎?靠爸難道就是真理嗎?

不過換個方式想,其實,努力並不總是孩子的事情,不是說爸爸擺爛,家裡的兒子是天才而且很努力,就會成功,而是爸爸跟兒子都要一起努力才可以。

今天我們把努力的爸爸提升起來,z-index 改為 2,這樣他的兒子就會贏了:

.very-rich {
  z-index: 2;
}

.work-hard {
  z-index: 2;
}

.general {
  z-index: 1;
}

.genius {
  z-index: 9999;
}

小結

過去我們初淺的理解 z-index 時,總是以為只要值越大,他就會排在最上面。在一般簡單的狀況下,這樣的規則是沒錯的,但事實上,精確的來說,我們會需要考慮他的堆疊上下文(stacking context),本文提到的「靠爸」特性就是其中一個,你不能只考慮你自己,你也要考慮到你的家庭環境,考慮到你爸。所以,事實上,z-index 的特性往往比我們想的還要複雜。

希望本篇點出這個問題之後,讀者能夠在使用 z-index 時更加留意,理解他,並有規劃的使用。如果只是一味的增加 z-index,這樣到最後,整個堆疊環境越來越複雜的時候,我們要決定誰在上面、誰在下面,就會變成一個複雜的難題。


上一篇
【Day28】CSS 語法 - 隱藏網頁上的元件
下一篇
【Day30】完賽心得
系列文
防禦性 CSS - 建立「防患未然」的匠人心態30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言