avatarSchaos

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

2497

Abstract

畫面就好,不用全螢幕都重新繪製。</p></blockquote><p id="5c80">另外,堆疊環境也會影響到畫面的 z 軸排列順序。</p><p id="4df1">回頭看一下剛剛提到的 <code>z-index</code> 定義,<code>z-index</code> 的影響範圍就只有在它所在的堆疊環境中;因此要確認兩元素的排列順序,必須先確認元素個別所在的堆疊環境順序,若在同一個堆疊環境,才比較兩者的 <code>z-index</code></p><p id="be19">可以參考底下這個 <a href="https://codepen.io/GaryChu/pen/wvwQWjE"><b>MDN 的範例</b></a></p><figure id="2936"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*tKYzU3tPY2_LrvX4.jpg"><figcaption></figcaption></figure><p id="b488">範例中的 <code>#div1</code><code>#div2</code><code>#div3</code> 是同層元素,共用了最外層的「根堆疊環境(Root Stacking Context)」,而 <code>#div4</code><code>#div5</code><code>#div6</code> 則是 <code>#div3</code> 的子元素。</p><p id="1432">由於 <code>#div3</code> 有設定 <code>position: absolute</code><code>z-index: 3</code>,它會產生一個新的堆疊環境,即使 <code>#div2</code><code>z-index</code> 大於 <code>#div5</code><code>z-index</code>,卻因為它們存在於不同的堆疊環境中,它們之間不會直接比較,而是從共用堆疊環境的 <code>#div2</code><code>#div3</code> 中 比較 <code>z-index</code>,來決定 z 軸上的排列順序。</p><h2 id="f693">建立堆疊環境</h2><p id="674e">要建立一個新的堆疊環境非常容易,比較常用到的有以下幾種方式:</p><ul><li>根元素(<code><html></html></code></li><li><code>position</code> 設定成 <code>fixed</code><code>sticky</code></li><li><code>position</code> 設定成 <code>relative</code><code>absolute</code> & 有設定 <code>z-index</code></li><li>有設定 <code>transform</code> 屬性</li><li><code>opacity</code> 的值設定小於 1</li></ul><p id="d3ab">另外,開發者可以透過瀏覽器 DevTools 的 Layers 頁籤,觀察目前的頁面有哪些圖層:</p><figure id="7942"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*N3EiNwfSwZF0uW5Y.jpg"><figcaption></figcaption></figure><p id="c70d">如同前述,瀏覽器會將所有圖層做疊加運算;當圖層過多時也會稍微影響效能,在撰寫 CSS 時要稍微留心喔!</p><h2 id="bf33">延伸閱讀</h2><p id="4b89">雖然聊了兩天的 CSS 中相對深入的主題,但對於瀏覽器渲染畫面這塊仍然只帶到皮毛;關於 Render Tree 轉換成堆疊環境的過程,讀者如果想要進一步探究的話,可以參考 <a href="https://blog.csdn.net/luoshengyang/article/details/50661553">這篇</a>,但內容會偏離 CSS 太遠,這邊就不繼續深入了。</p><h1 id="92b9">結語</h1><p id="ab14">在研究這個主題時,突然發現很多以前覺得 CSS 玄妙的地方,好像都可以跟 Stacking Context 扯上關係;例如設定絕對定位時為什麼是參考外層的 positioned box 等等,真的有種被醍醐灌頂、打通任督二脈的感覺;果然在理解基本原理之後,許多難懂的知識點都可以迎刃而解!</p><p id="c617">聊了兩天的 CSS 明天就是 CSS 的最後一部啦!以上就是今天的 Stacking Context,如果本文有任何錯誤或不清楚的地方,都歡迎讀者您在底下留言回應!這場每天讓自己更好的旅程將會繼續下去,大家明天見囉~</p><h2 id="995c">參考資料</h2><ul><li><a href="https://drafts.csswg.org/css2/visuren.html#propdef-z-index">CSS2–9.9 Layered presentation</a></li><li><a href="https://www.w3.org/TR/CSS2/zindex.html">CSS2 — Appendix E. Elaborate description of Stacking Contexts</a></li><li><a href="https://developer.

Options

mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index">MDN — Understanding CSS z-index</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flow_Layout/In_Flow_and_Out_of_Flow">MDN — In Flow and Out of Flow</a></li><li><a href="https://developers.google.com/web/fundamentals/performance/rendering/">Google Web Fundamentals Guides — 轉譯效能</a></li><li><a href="https://zh.wikipedia.org/wiki/%E6%8E%92%E7%89%88%E5%BC%95%E6%93%8E">WIKI — 排版引擎</a></li></ul><blockquote id="da44"><p>本文同步發表於 2020 IT 邦幫忙鐵人賽</p></blockquote><div id="0ece" class="link-block"> <a href="https://ithelp.ithome.com.tw/articles/10217945"> <div> <div> <h2>04. [CSS] z-index 與 Stacking Context 的關係是什麼? - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天</h2> <div><h3>不知道大家有沒有這樣的經驗:在排版時無論 z-index 怎麼調整,元素仍然被其他東西蓋住,怎麼調都調不好;今天我們將會深入理解這背後的原因,一起來聊聊 z-index 及與它相關的 堆疊環境(Stacking Context) 。…</h3></div> <div><p>ithelp.ithome.com.tw</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*6jXOaMxHvJA6DT_H)"></div> </div> </div> </a> </div> <figure id="1f12"> <div> <div> <img class="ratio" src="http://placehold.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fbutton.like.co%2Fin%2Fembed%2Fgary_chu%2Fbutton%2F&amp;display_name=LikeCoin&amp;url=https%3A%2F%2Fbutton.like.co%2Fgary_chu&amp;image=https%3A%2F%2Fstorage.googleapis.com%2Flikecoin-foundation.appspot.com%2Flikecoin_store_user_gary_chu_main%3FGoogleAccessId%3Dfirebase-adminsdk-eyzut%2540likecoin-foundation.iam.gserviceaccount.com%26Expires%3D2430432000%26Signature%3DaXjCoEbugypUZYmd75UwfXbcjRPYubsy0yc6%252B%252F7hKFeIA0qXeK2XqNEq%252Fys92tnzbgKR4uDsZAuItD40lcXj8Y8FMaL0c2XLbU%252F4Tb%252BUhxON5sa%252Bbr0COKv1WF7tzXKi0u%252BaQru2HBaGDnSXLdQzTRwvGA584CPni2xMbd0OryOsfI1%252FWBFvGwM5EJLQ%252BXgDmm9j1Cr7oFhk9RUx%252F5mLOCvSPn7Nt01bN%252BLilHnq0pmGpvDssDwo53WgdYitBCv%252BlstkgGwIkrKJzbl4LFkIyG%252Flv2fA1g8ixnaJuwMVvLwoq5p%252Br9x05h847wChnTYR1nSntmBGFHtcfqd%252Fofc%252F0A%253D%253D&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=like" allowfullscreen="" frameborder="0" height="212" width="485"> </div> </div> </figure></iframe></div></div></figure></article></body>

前端三十|04. [CSS] z-index 與 Stacking Context 的關係是什麼?

不知道大家有沒有這樣的經驗:在排版時無論 z-index 怎麼調整,元素仍然被其他東西蓋住,怎麼調都調不好;今天我們將會深入理解這背後的原因,一起來聊聊 z-index 及與它相關的 堆疊環境(Stacking Context)

本系列文已經重新編校彙整編輯成冊,並正式出版囉!

前端三十:從 HTML 到瀏覽器渲染的前端開發者必備心法好評販售中!

喜歡我文章內容的讀者們,歡迎您前往購買支持

z-index

相信這個 CSS 屬性大家應該都不陌生,是用來指定元素在 z 軸的「高度」(越大越靠近使用者);在 CSS2.1 的規格 中指明:

For a positioned box, the ‘z-index’ property specifies:

1. The stack level of the box in the current stacking context. 2. Whether the box establishes a stacking context.

這邊的 positioned box 指的是 position 屬性不為預設值(static)的元素(box 指盒模型);所以 z-index 即為指定元素在 堆疊環境 中的 堆疊層級,且它只在 positioned box 上生效。

眼尖的同學應該已經注意到了,又出現了 昨天文章 就已經提到過的 Stacking Context,那麼它究竟是什麼呢?

堆疊環境 Stacking Context

在網頁排版時,預設的元素排列會是由上到下、由左到右的依序排列;開發者如果想要調整或固定特定元素的位置,會透過設定 positionrelativeabsolutefixed,讓指定的元素可以從原本的排列位置移動,甚至離開(Out of Flow)。而這時,也就產生了一個新的 CSS 堆疊環境,從此這個元素及它的子元素,就自成一國,他們的排列也就與其他的堆疊環境無關了。

功能

那這些自成一國的堆疊環境,對開發者來說有什麼影響呢?

很簡單!堆疊環境內的元素、屬性變動,是不會觸發其他堆疊環境的回流(Reflow)的喔~

昨天討論的瀏覽器的渲染步驟,其實還有最後一步:一個 Render Tree 經過計算後會轉換成許多堆疊環境,也可以理解成 圖層;我們先前聊過的「計算定位(Layout、Reflow)」、「繪製像素(Paint)」,這些步驟會發生在每一個圖層上,而瀏覽器會在最後的步驟「合成(Composite)」時,將這些圖層做疊加計算。

你可能會想問,為什麼不先疊加計算再繪製像素?

同樣的,是因為要讓各圖層的計算不會互相影響;如果某圖層只覆蓋到部分螢幕,當它樣式變動時,也只需要重算該圖層包含的部分畫面就好,不用全螢幕都重新繪製。

另外,堆疊環境也會影響到畫面的 z 軸排列順序。

回頭看一下剛剛提到的 z-index 定義,z-index 的影響範圍就只有在它所在的堆疊環境中;因此要確認兩元素的排列順序,必須先確認元素個別所在的堆疊環境順序,若在同一個堆疊環境,才比較兩者的 z-index

可以參考底下這個 MDN 的範例

範例中的 #div1#div2#div3 是同層元素,共用了最外層的「根堆疊環境(Root Stacking Context)」,而 #div4#div5#div6 則是 #div3 的子元素。

由於 #div3 有設定 position: absolutez-index: 3,它會產生一個新的堆疊環境,即使 #div2z-index 大於 #div5z-index,卻因為它們存在於不同的堆疊環境中,它們之間不會直接比較,而是從共用堆疊環境的 #div2#div3 中 比較 z-index,來決定 z 軸上的排列順序。

建立堆疊環境

要建立一個新的堆疊環境非常容易,比較常用到的有以下幾種方式:

  • 根元素(<html></html>
  • position 設定成 fixedsticky
  • position 設定成 relativeabsolute & 有設定 z-index
  • 有設定 transform 屬性
  • opacity 的值設定小於 1

另外,開發者可以透過瀏覽器 DevTools 的 Layers 頁籤,觀察目前的頁面有哪些圖層:

如同前述,瀏覽器會將所有圖層做疊加運算;當圖層過多時也會稍微影響效能,在撰寫 CSS 時要稍微留心喔!

延伸閱讀

雖然聊了兩天的 CSS 中相對深入的主題,但對於瀏覽器渲染畫面這塊仍然只帶到皮毛;關於 Render Tree 轉換成堆疊環境的過程,讀者如果想要進一步探究的話,可以參考 這篇,但內容會偏離 CSS 太遠,這邊就不繼續深入了。

結語

在研究這個主題時,突然發現很多以前覺得 CSS 玄妙的地方,好像都可以跟 Stacking Context 扯上關係;例如設定絕對定位時為什麼是參考外層的 positioned box 等等,真的有種被醍醐灌頂、打通任督二脈的感覺;果然在理解基本原理之後,許多難懂的知識點都可以迎刃而解!

聊了兩天的 CSS 明天就是 CSS 的最後一部啦!以上就是今天的 Stacking Context,如果本文有任何錯誤或不清楚的地方,都歡迎讀者您在底下留言回應!這場每天讓自己更好的旅程將會繼續下去,大家明天見囉~

參考資料

本文同步發表於 2020 IT 邦幫忙鐵人賽

前端三十
CSS
Stacking Context
Z Index
Recommended from ReadMedium