css z-index屬性

来源:http://www.cnblogs.com/quinnhow/archive/2016/04/20/5411887.html
-Advertisement-
Play Games

原文地址:http://www.neoease.com/css-z-index-property-and-layering-tree/ CSS 中的 z-index 屬性用於設置節點的堆疊順序, 擁有更高堆疊順序的節點將顯示在堆疊順序較低的節點前面, 這是我們對 z-index 屬性普遍的認識. 與 ...


原文地址:http://www.neoease.com/css-z-index-property-and-layering-tree/

CSS 中的 z-index 屬性用於設置節點的堆疊順序, 擁有更高堆疊順序的節點將顯示在堆疊順序較低的節點前面, 這是我們對 z-index 屬性普遍的認識. 與此同時, 我們總是對堆疊順序捉摸不透, 將 z-index 的值設得很大也未必能將節點顯示在最前面. 本文將通過一些例子對 z-index 的使用方法進行分析, 並且為各位帶入 z-index 層級樹的概念.

 

這個星期我們團隊做了一次內部的技術分享, 南瓜小米粥為我們分享了他對 CSS z-index 的理解和引入層級樹這個概念. 這個分享的現場效果很好, 所以我也將 z-index 和層級樹話題搬到博客來談一談.

本文談及多個影響節點顯示層級的規則, 其中用到的所有例子全部羅列在《position 屬性和 z-index 屬性對頁面節點層級影響的例子》中.

目錄

順序規則

如果不對節點設定 position 屬性, 位於文檔流後面的節點會遮蓋前面的節點.

<div id="a">A</div>
<div id="b">B</div>

CSS z-index 屬性順序規則的例子

定位規則

如果將 position 設為 static, 位於文檔流後面的節點依然會遮蓋前面的節點浮動, 所以 position:static 不會影響節點的遮蓋關係.

<div id="a" style="position:static;">A</div>
<div id="b">B</div>

CSS z-index 屬性定位規則的例子, static

如果將 position 設為 relative (相對定位), absolute (絕對定位) 或者 fixed (固定定位), 這樣的節點會覆蓋沒有設置 position 屬性或者屬性值為 static 的節點, 說明前者比後者的預設層級高.

<div id="a" style="position:relative;">A</div>
<div id="b">B</div>

CSS z-index 屬性定位規則的例子, relative | absolute | fixed

在沒有 z-index 屬性干擾的情況下, 根據這順序規則和定位規則, 我們可以做出更加複雜的結構. 這裡我們對 A 和 B 都不設定 position, 但對 A 的子節點 A-1 設定 position:relative. 根據順序規則, B 會覆蓋 A, 又根據定位規則 A' 會覆蓋 B.

<div id="a">
	<div id="a-1" style="position:relative;">A-1</div>
</div>
<div id="b">B</div>

CSS z-index 屬性互相覆蓋的例子

上面互相覆蓋在什麼時候用到這樣的實現? 看起來偏門, 其實很常用, 比如說, 電子商務網站側欄的類目展示列表就可以用這個技巧來實現.

下圖是某網站的類目展示區域, 二級類目的懸浮層覆蓋一級類目列表外框, 而一級類目的節點覆蓋二級類目的懸浮層. 如果使用 CSS 實現展示效果, 一級類目的外框相當於上面例子中的 A, 一級類目的節點相當於 A-1, 二級類目的懸浮層相當於 B.

電子商務網站側欄的類目展示列表

參與規則

我們嘗試不用 position 屬性, 但為節點加上 z-index 屬性. 發現 z-index 對節點沒起作用.

<div id="a" style="z-index:2;">A</div>
<div id="b" style="z-index:1;">B</div>
<div id="c" style="z-index:0;">C</div>

CSS z-index 屬性參與規則的例子, 沒有明確定位的時候

W3C 對 z-index 屬性的描述中提到 在 z-index 屬性僅在節點的 position 屬性為 relative, absolute 或者 fixed 時生效.

The z-index property specifies the stack order of an element. Only works on positioned elements(position: absolute;, position: relative; or position: fixed;).

<div id="a" style="z-index:2;">A</div>
<div id="b" style="position:relative;z-index:1;">B</div>
<div id="c" style="position:relative;z-index:0;">C</div>

CSS z-index 屬性參與規則的例子, 明確定位的節點才能使用 z-index 屬性

預設值規則

如果所有節點都定義了 position:relative. z-index 為 0 的節點與沒有定義 z-index 在同一層級內沒有高低之分; 但 z-index 大於等於 1 的節點會遮蓋沒有定義 z-index 的節點; z-index 的值為負數的節點將被沒有定義 z-index 的節點覆蓋.

<div id="a" style="position:relative;z-index:1;">A</div>
<div id="b" style="position:relative;z-index:0;">B</div>
<div id="c" style="position:relative;">C</div>
<div id="d" style="position:relative;z-index:0;">D</div>

CSS z-index 屬性預設值規則的例子

通過檢查我們還發現, 當 position 設為 relative, absolute 或者 fixed, 而沒有設置 z-index 時, IE8 以上和 W3C 瀏覽器 (下文我們統稱為 W3C 瀏覽器) 的 z-index 預設值是 auto, 但 IE6 和 IE7 是 0.

從父規則

如果 A, B 節點都定義了 position:relative, A 節點的 z-index 比 B 節點大, 那麼 A 的子節點必定覆蓋在 B 的子節點前面.

<div id="a" style="position:relative;z-index:1;">
	<div id="a-1">A-1</div>
</div>
 
<div id="b" style="position:relative;z-index:0;">
	<div id="b-1">B-1</div>
</div>

CSS z-index 屬性從父規則的例子, 子節點不設定層級

如果所有節點都定義了 position:relative, A 節點的 z-index 和 B 節點一樣大, 但因為順序規則, B 節點覆蓋在 A 節點前面. 就算 A 的子節點 z-index 值比 B 的子節點大, B 的子節點還是會覆蓋在 A 的子節點前面.

<div id="a" style="position:relative;z-index:0;">
	<div id="a-1" style="position:relative;z-index:2;">A-1</div>
</div>
 
<div id="b" style="position:relative;z-index:0;">
	<div id="b-1" style="position:relative;z-index:1;">B-1</div>
</div>

CSS z-index 屬性從父規則的例子, 不可逾越的層級

很多人將 z-index 設得很大, 9999 什麼的都出來了, 如果不考慮父節點的影響, 設得再大也沒用, 那是無法逾越的層級.

層級樹規則

可能你會覺得在 DOM 結構中的兄弟節點會拎出來進行比較並確定層級, 其實不然.

<div id="a" style="position:relative;z-index:2;">
	<div id="a-1" style="position:relative;z-index:0;">A-1</div>
</div>
 
<div id="b">
	<div id="b-1" style="position:relative;z-index:1;">B-1</div>
</div>

CSS z-index 屬性層級樹規則的例子

我們認為同時將 position 設為 relative, absolute 或者 fixed, 並且 z-index 經過整數賦值的節點, 會被放置到一個與 DOM 不一樣的層級樹裡面, 並且在層級樹中通過對比 z-index 決定顯示的層級. 上面的例子如果用層級樹來表示的話, 應該如下圖所示.

CSS z-index 的層級樹

圖中雖然 A-1 (z-index:0) 的值比 B-1 (z-index:1) 小, 但因為在層級樹里 A (z-index:2) 和 B-1 在一個層級, 而 A 的值比 B-1 大, 根據從父規則, A-1 顯示在 B-1 前面.

參與規則 2

前面提到的參與規則認為只要節點的 position 屬性為 relative, absolute 或者 fixed, 即可參與層級比較, 其實不准確. 如果所有節點都定義了 position:relative, 並且將 z-index 設為整數值, 根據從父規則, 父節點的層級決定了子節點所在層級.

<div id="a" style="position:relative;z-index:0;">
	<div id="a-1" style="position:relative;z-index:100;">A-1</div>
</div>
 
<div id="b">
	<div id="b-1" style="position:relative;z-index:0;">
		<div id="b-1-1" style="position:relative;z-index:10;">B-1-1</div>
	</div>
</div>
 
<div id="c" style="position:relative;z-index:0;">
	<div id="c-1">
		<div id="c-1-1">
			<div id="c-1-1-1" style="position:relative;z-index:1;">C-1-1-1</div>
		</div>
	</div>
</div>

例子中 A, B-1, C-1-1 作為父節點, z-index 的值相同, 根據順序規則, C-1-1 在 B-1 之前, B-1 在 A 之前; 又根據從父規則, 無論子節點的 z-index 值是什麼, C-1-1-1 在 B-1-1 之前, B-1-1 在 A-1 之前.

CSS z-index 屬性參與規則 2 的例子, 所有節點參與層級比較

如果我們將所有父節點的 z-index 屬性去除, 詭異的事情發生了. IE6 和 IE7 瀏覽器顯示效果不變, 而 W3C 瀏覽器的子節點不再從父, 而是根據自身的 z-index 確定層級.

<div id="a" style="position:relative;">
	<div id="a-1" style="position:relative;z-index:100;">A-1</div>
</div>
 
<div id="b">
	<div id="b-1" style="position:relative;">
		<div id="b-1-1" style="position:relative;z-index:10;">B-1-1</div>
	</div>
</div>
 
<div id="c" style="position:relative;">
	<div id="c-1">
		<div id="c-1-1">
			<div id="c-1-1-1" style="position:relative;z-index:1;">C-1-1-1</div>
		</div>
	</div>
</div>

根據預設值規則, IE6 / IE7 和 W3C 瀏覽器上的元素存在 z-index 預設值的區別. 我們相信, 僅當 position 設為 relative, absolute 或者 fixed, 並且 z-index 賦整數值時, 節點被放置到層級樹; 而 z-index 為預設值時, 只在 document 兄弟節點間比較層級. 在 W3C 瀏覽器中, A, B-1 和 C-1-1 的 z-index 均為 auto, 不參與層級比較.

CSS z-index 屬性參與規則 2 的例子, z-index 為 auto 的節點不參與層級比較

而在 IE6 和 IE7 中, 因為 z-index 的預設值是 0, 所以也參與了層級比較.

CSS z-index 屬性參與規則 2 的例子, IE6 和 IE7 中 z-index 預設為 0

設置了 position 而沒有 z-index 的節點雖然不參與層級樹的比較, 但還會在 DOM 中與兄弟節點進行層級比較.

<div id="a" style="position:relative;">
	<div id="a-1" style="position:relative;z-index:100;">A-1</div>
</div>
 
<div id="b">
	<div id="b-1">
		<div id="b-1-1" style="position:relative;z-index:10;">B-1-1</div>
	</div>
</div>
 
<div id="c" style="position:relative;">
	<div id="c-1">
		<div id="c-1-1">
			<div id="c-1-1-1" style="position:relative;z-index:1;">C-1-1-1</div>
		</div>
	</div>
</div>

我們對上個例子改造一下, 將 B-1 的 position 屬性刪除後, W3C 瀏覽器顯示如下圖. 根據定位規則, A 和 C-1-1 會顯示在 B-1 的前面; 而根據順序規則, C-1-1 又顯示在 A 前面.

CSS z-index 屬性參與規則 2 的例子, position 為 auto 的節點不參與層級樹比較, 但仍參與 DOM 兄弟節點間的層級比較, W3C 瀏覽器

在 IE6 和 IE7 中, 因為 A 和 C-1-1 設置了 position:relative, 而且 z-index 的預設值為 0, 所以也參與層級樹比較, 所以有如下效果.

CSS z-index 屬性參與規則 2 的例子, position 為 auto 的節點不參與層級樹比較, 但仍參與 DOM 兄弟節點間的層級比較, IE6 和 IE7

總結

瀏覽器節點顯示層級是一個費力的活, 今天你覺得 A 區塊會永遠置頂, 但明天因為需求變動, 突然出現 B 元素需要置頂. 一層一層往上堆砌, 某天回頭一看, 發現很多區塊交錯在一起, 而且他們的值一個比一個大, 根本搞不清頭緒. 我覺得在操刀幹活之前, 最好先將 position, z-index 和層級的關係搞搞清楚, 以免後患無窮.

另外, 非情非得已, 切勿用 JavaScript 計算 z-index, 並將某個節點的 z-index 設置成所有節點中層級最高.

因為篇幅太長, 本文僅從節點屬性角度進行討論, 沒有涉及 select 和 iframe 等特殊頁面節點考慮, 如果有機會下次再為大家分享.

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原型模式就是從一個對象再創建另一個可定製的對象,而不需要知道任何創建的細節。 原型模式本身是比較簡單的,不過其中牽涉到淺複製和深複製的實現,下麵使用.Net自帶的方法和介面分別實現淺複製和深複製: MemberwiseClone方法實現的是淺複製,即如果欄位是值類型,則對該欄位執行逐位複製,如果欄位 ...
  • 一直覺得有些概念還離著自己比較遠,比如ES6,比如React,比如Redux,雖說這些概念早已經火的一塌糊塗,每天逛微博知乎到處都是他們的身影,但感覺好像和自己沒什麼關係。不過最近要開始一個新的項目,一個webapp,開始依然像我以前一樣,頂級組件處理處理邏輯和數據,數據通過組件屬性分發下去,邏輯通 ...
  • 1.圖片寬高固定,這種情況很簡單。水平居中:就在圖片的css中加 dispaly:block;margin:0 auto;垂直居中:自己算出(div的高度-圖片的高度)/2,得到margin-top值即可。2.圖片高度未知,這個佈局比較難實現。一般我是用js做的。水平居中:同上,在圖片的css中加 ...
  • 效果:http://hovertree.com/texiao/jquery/50/現在許多社區,購物等網站都設置簽到功能,打開可以收穫經驗、虛擬幣等,提高用戶粘性,增加瀏覽量,是一個不錯的功能。本文使用jQuery製作了一個簡單的打卡特效。現在jQuery的應用十分廣泛,這裡提供全部版本的jQuer ...
  • 今天遇到一個問題:怎樣實現點擊一個按鈕,在當前的頁面上新增加一個小視窗,展示一個圖片信息? 如圖: 點擊之前: 單擊之後: 分析:要使新增的小視窗不影響父頁面,我們這裡採用iframe的框架的技術。 【<iframe>也應該是框架的一種形式,它與<frame>不同的是,iframe可以嵌在網頁中的任 ...
  • 前言: 創建元素有兩種方法 1)將需要創建的元素,以字元串的形式拼接;找到父級元素,直接對父級元素的innnerHTML進行賦值。 2)使用Document、Element對象自帶的一些函數,來實現動態創建元素(創建元素 => 找到父級元素 => 在指定位置插入元素) 一、字元串拼接形式 為了更好的 ...
  • "你從哪裡來?” “你要到哪裡去?" 這是保全小哥經常會問的具有哲理性的問題。在互聯網的應用的開發中,也經常會用到有關地址的選擇設置。不管是物流的應用,還是外賣的應用,都會要求用戶設置用戶所在的位置。如果讓用戶來輸入完整的地址,一方面,輸入比較慢,體驗不好。另一方面,輸入的地址不規範,例如:"浙江省 ...
  • 本文章向碼農介紹css3選擇器的使用方法和總結,包括通用選擇器,屬性選擇器,偽類選擇器,對css選擇器相關知識感興趣的碼農可以閱讀一下本文章。 一 通用選擇器 1 *{}通配選擇符(CSS2):適合所有元素對象。2 E類型(HTML)選擇符(CSS1):以文檔語言對象類型DOM作為選擇符。3 E#m ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...