不起眼的 z-index 卻能牽扯出這麼大的學問

来源:http://www.cnblogs.com/bfgis/archive/2016/04/27/5440956.html
-Advertisement-
Play Games

z-index在日常開發中算是一個比較常用的樣式,一般理解就是設置標簽在z軸先後順序,z-index值大的顯示在最前面,小的則會被遮擋,是的,z-index的實際作用就是這樣。 但是你真的瞭解z-index嗎?你知道它有什麼特性嗎?這裡先拋出幾個名詞:“層疊順序(stacking order)”,“ ...


z-index在日常開發中算是一個比較常用的樣式,一般理解就是設置標簽在z軸先後順序,z-index值大的顯示在最前面,小的則會被遮擋,是的,z-index的實際作用就是這樣。

但是你真的瞭解z-index嗎?你知道它有什麼特性嗎?這裡先拋出幾個名詞:“層疊順序(stacking order)”,“層疊上下文(stacking context)”,“層疊水平(stacking level)”。

先說一下z-index的基本用法:  

  z-index可以設置成三個值:

  • auto,預設值。當設置為auto的時候,當前元素的層疊級數是0,同時這個盒不會創建新的層級上下文(除非是根元素,即<html>);
  • <integer>。指示層疊級數,可以使負值,同時無論是什麼值,都會創建一個新的層疊上下文;
  • inherit。父元素繼承   

z-index只在定位元素中起作用,舉慄子:

<style>
    #box1{
        background: blue;
        width: 200px;
        height: 200px;
    }
    #box2{
        background: yellow;
        width: 200px;
        height: 200px;
        margin-top:-100px;
    }
       
</style>
<div id="box1"></div>
<div id="box2"></div>    

我們希望box1要顯示在box2上面,可能這時候有同學會說,給box1加一個z-index大於0的值就可以了,這樣是不對的,如圖:

box2遮擋了box1,即使box1設置z-index值再大也白搭,前面說了z-index只在定位元素(position=static除外,因為元素預設就是static,相當於沒用position樣式)中作用,也是就z-index要配合position一起使用感興趣的可以親自驗證一下,這裡只拋磚引玉。

層疊順序對絕對元素的Z軸順序

層疊順序其實不是z-index獨有的,每個元素都有層疊順序,元素渲染的先後順序跟它有很大關係,總之當元素髮生層疊時,元素的層級高的會優先顯示在上面,層級一樣的則會根據dom的先後順序進行渲染,後面的會覆蓋前面的。文字再多可能也沒有一張圖來的直接,下麵這張圖是“七階層疊水平”(網上盜的,很經典的一張圖)

 

再舉個慄子,這裡還是拿剛纔那個慄子來說,在不用z-index的前提下,利用css層疊順序解決遮擋問題,代碼修改如下

<style>
    #box1{
        background: blue;
        width: 200px;
        height: 200px;
        display:inline-block;
    }
    #box2{
        background: yellow;
        width: 200px;
        height: 200px;
        margin-top:-100px;
    }
       
</style>
<div id="box1"></div>
<div id="box2"></div>   

這裡只做了細微的修改,就是給box1加了一個display:inline-block;的樣式,這裡解釋一下,首先box1和box2發生了層疊,然後box預設為塊級元素,即display:block,從七階圖中看出,display:block的元素的層疊水平低於display:inline-block的元素,所以瀏覽器就將box2渲染到box1上面,如圖:

靈活的運用七階圖可以讓你的代碼儘可能的減少z-index的使用。因為多個人開發同一個系統,如果過多的用z-index,很有可能會出現衝突,即遮擋問題,一般來說z-index使用10以內的數值就足夠了。

重點:層疊上下文

  先說一下如果創建層疊上下文,css創建層疊上下文的方法有很多,但是常用的也就夠那麼幾種

  1、定位元素中z-index不等於auto的會為該元素創建層疊上下文

  2、html根元素預設會創建層疊上下文(這是一個特例,知道就行)

  3、元素的opacity不等於1會創建層疊上下文

  4、元素的transform不等於none會創建層疊上下文

還有其它方式創建層疊上下文,這裡就不做介紹了,上面四中是開發中常用到的。

那麼知道怎麼創建層疊上下文之後,問題的關鍵來了,層疊上下文有什麼用呢?

這裡一定要結合前面那張七階圖,最下麵那一層便background是建立在層疊上下文的基礎上的,也就是說在層疊上下文中,所有的元素都會渲染在背景和邊框上面;在block盒子、float盒子等不存在層級上下文的元素中,子元素設置z-index為負值的時候,那麼子元素會被父元素遮擋。說了可能不太好理解,舉個慄子消化一下:

 

<style>
    #box1{
        position: relative;
        width: 200px;
        height: 200px;
        background: blue;
    }
    #box2{
        position: relative;
        z-index:-1;
        width: 100px;
        height: 100px;
        background: yellow;
    }
</style>

<div id="box1">
      <div id="box2"></div>
</div>

 

這裡,box並沒有創建層疊上下文,當子元素box2設置z-index:-1時,box2所在的層疊上下文是根元素,即html根標簽,根據七階圖可以看出,box2會渲染在html標簽上面,普通盒子box1(z-index:auto)下麵,所以box2被遮擋了。如圖所示:

那麼怎麼解決這個問題呢?相信大家已經知道這裡該怎麼處理了吧,是的,為box1建立一個層疊上下文,那麼box1中的元素無論z-index是負的多少,都會顯示在box1的背景之上,如圖:

這裡我用了前面說的的第一種方式去創建層疊上下文,即定位元素中z-index不為auto的元素會建立層疊上下文,可能有的同學開始納悶了,box1的z-index小於box2的z-index,為什麼box2缺顯示在box1的上面呢?呵呵,這正對應了七階圖的層疊水平的關係,不明白的再仔細揣摩一下七階圖

· 層疊水平僅在直接父級層疊上下文中進行比較,即層疊上下文A中的子元素的層疊水平不會和另一個層疊上下文中的子元素進行比較。舉個例子

<style>
    #box1{
        z-index: 10;
        position: relative;
        width: 200px;
        height: 200px;
        background: green;
    }
    #box1_1{
        position: relative;
        z-index: 100;
        width: 100px;
        height: 100px;
        background: blue;
    }
    #box2{
        position: relative;
        z-index: 11;
        width: 200px;
        height: 200px;
        background: red;
        margin-top: -150px;
    }
</style>

<div id="box1">
    <div id="box1_1">    
    </div>
</div>

<div id="box2">
 
</div>

層疊上下文box1中的子元素box2設置z-index為100,而層疊上下文box2的z-index只有11,而實際的渲染效果卻是,box2在box1和box1_1的上面,這就應了上面那就話,層疊水平僅在元素的第一個父級層疊上下文中進行,即層疊上下文A中的子元素的層疊水平不會和另一個層疊上下文中的子元素進行比較,也就是活box1_1的z-index對於他的父級層疊上下文之外的元素沒有任何影響。這裡box2和box1在同一個層疊上下文中(html根元素會預設創建層疊上下文),所以它們兩個會進行層疊水平的比較,box2的z-index大於box1的z-index,所以我們看到的也就是下麵這樣,box2遮擋了box1,不在乎box1中的子元素z-index是多少,如圖:

這裡我對z-index的理解也就講述完畢了,大概就說了以下這幾點內容:

  1、z-index僅在定位元素(position不等於static)中有效

  2、七階層疊水平圖

  3、z-index層疊水平的比較僅限於父級層疊上下文中

其次需要註意以下幾點:

  1、在開發中儘量避免層疊上下文的多層嵌套,因為層疊上下文嵌套過多的話容易產生混亂,如果對層疊上下文理解不夠的話是不好把控的。

  2、非浮層元素(對話框等)儘量不要用z-index(通過層疊順序或者dom順序或者通過層疊上下文進行處理)

  3、z-index設置數值時儘量用個位數

用了一晚上的時間整理了這篇文章,就連我自己對z-index也有了更加深刻的理解,希望對你也有幫助。如有錯誤 歡迎指正

 


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

-Advertisement-
Play Games
更多相關文章
  • ...
  • 上一篇:《 "DDD 領域驅動設計-如何控制業務流程?" 》 開源地址: "https://github.com/yuezhongxin/CNBlogs.Apply.Sample" (代碼已更新,並增加了應用層代碼) 在 JsPermissionApply 領域模型中,User 被設計為值對象,也就 ...
  • 第一章介紹了android系統移植與驅動開發的一些基本的概念,我做瞭如下總結: 一、android的系統架構分為四層 第一層是linux內核層 第二層是c/c++代碼庫 第三層是android Sdk API 第四層是應用程式層 android系統移植與驅動開發主要就是在linux內核層上進行的。a ...
  • oaoDailog開發幫助 1. 幫助文檔關鍵字 boostrap模態框oaoDailog 2. 使用場景 當網頁上點擊某個按鈕需要給予用戶提示確認,用戶點擊確認按鈕才能繼續執行,或者用戶點擊取消按鈕則取消執行操作; 當網頁上點擊查看,展示的數據需要使用彈出框展示的情況下,可以使用oaoDailog ...
  • Stylus是一款需要編譯的css語言,所以其本身文件不能被html直接調用,需要要編譯為css文件後再進行日常的載入。 stylus是一款優秀的css編譯語言,需要node.js支持,第一步需要安裝node.js 問題:Windows調試時ctrl+d無效果 ctrl+c退出? 怎樣直接在wind ...
  • 前兩天編寫了一個前端頁面,在本機上顯示一切正常。不過在不斷的測試中,發現了一個嚴重的問題,如果圖片過大,會撐破div溢出來。再由於頁面是自適應頁面,根據不同解析度的顯示器會做出相應的div寬度調整,所以圖片即使不大,但是因解析度不同也會出現溢出的情況。 這裡探討總結一下解決方法。 首先我們先來做個簡 ...
  • CSS3新特性,相容性,相容方法總結 css3手冊 "css3手冊" 邊框 border radius 用於添加圓角效果 語法: 用長度值設置對象的圓角半徑長度。不允許負值 用百分比設置對象的圓角半徑長度。不允許負值 實例: 相容性: IE9+,Firefox4+,Chrome5+,Safari5+ ...
  • 1.rem和em、px 首先來說說em和px的關係 em是指字體高度 瀏覽器預設1em=16px,所以0.75em=12px;我們經常會在頁面上看到根元素寫的font-size:65%; 這樣em就成了16px*62.5=10em;這是顯示在頁面的字體大小是10px; 這樣12px=1.2em,10 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...