z-index基礎介紹:
三維座標空間裏,x軸一般用來表示水平位置,y軸來表示垂直位置,還有z軸來表示在紙面內外方向上的位置,像下面的圖片同樣:css
css容許的z-index的值是
● auto (自動,默認值)
● (整數)
● inherit (繼承)
當設置成整數時,值越大越靠近用戶。
若是有兩個元素放在了一塊兒,佔據了一塊共同的區域,那麼有着較大z-index值的元素就會掩蓋有着較低z-index值的元素在共同區域的那一部分。html
關於z-index的三個思考
● 當一個設置了z-index值的定位元素與正常的文檔流中的元素相互重疊的時候,誰會被置於上方?
● 當定位元素與浮動元素相互重疊的時候,誰會被置於上方?
● z-index必需要與定位一塊兒使用纔會生效嗎?
● z-index大的元素必定會遮擋z-index小的元素嗎?
解決上面的問題須要深刻理解z-index的原理,須要知道層疊上下文和層疊順序。css3
層疊上下文的概念:
層疊上下文就是html中的一個三維概念。至關於在水平面建立了一個z軸,有了層疊上下文的元素會離用戶更近。它包含了一組層疊層的元素。咱們所建立的每個網頁都有一個默認的層疊上下文,層疊上下文的根就是html,其餘的全部元素都會在這個層疊上下文佔據一個層疊水平,或高或低。web
層疊順序:
層疊順序:這是一種規則,表示元素髮生重疊時,在z軸上的顯示順序。
在一個層疊上下文中,有七種層疊順序:瀏覽器
(1) 背景和邊框:創建層疊上下文的元素的背景和邊框,層疊中的最低級別
(2) 負的z-index:z-index 爲負值時造成的層疊上下文
(3) 塊級盒子: 文檔流中正常的塊級元素
(4) 浮動盒子:非定位的浮動盒子
(5) 行內盒:文檔流內的行內級盒子
(6) z-index:0 定位元素,這些元素創建了新的層疊上下文。
(7) 正的z-index:層疊中的最高級別。佈局
頁面中內聯元素的層疊順序要比浮動元素和塊狀元素都高的緣由,浮動和塊級盒子主要用來佈局,而內聯的元素用來顯示頁面內容。因此比起他的要高。flex
ps: 圖上缺乏的信息
inline和inline-block是一個同一個level
z-index:0實際上和z-index:auto單純從層疊水平上看,是能夠當作是同樣的。spa
層疊順序規則
誰大誰上:當具備明顯的層疊水平標示的時候,好比說z-index值,在同一個層疊上下文領域,層疊水平值大的那一個覆蓋小的那一個
後來居上:當元素的層疊水平一致、層疊順序相同的時候,在DOM流中處於後面的元素會覆蓋前面的元素。3d
層疊上下文元素的特性
● 層疊上下文的層疊水平要比普通元素高;
● 層疊上下文能夠嵌套,內部層疊上下文及其全部子元素均受制於外部的層疊上下文。
● 每一個層疊上下文不會影響它的兄弟元素,當進行層疊變化或渲染的時,只和該元素的後代元素有關。
● 每一個層疊上下文是獨立的,當元素髮生層疊的時,它的層疊順序依賴在父層疊上下文的層疊順序中。code
層疊上下文的建立
(1)根層疊上下文:
指的是頁面根元素,也就是html元素。這就是爲何,絕對定位元素在left/top等值定位的時候,若是沒有其餘定位元素影響,會相對瀏覽器窗口定位的緣由。
(2)定位元素
含有position的值是relative或absolute的定位元素,以及FireFox/IE瀏覽器(Chrome等webkit內核瀏覽器是fixed的自動造成層疊上下文,無需將z-index設置成數值)下含有position:fixed的定位元素,當其z-index值不是auto的時候,會建立層疊上下文。
demo:
(1)
<div style="position:relative; z-index:auto;"> <img src="./cat.jpg" style="position:absolute; z-index:2;" class="cat"> </div> <div style="position:relative; z-index:auto;"> <img src="./dog.jpg" style="position:relative; z-index:1;" class="dog"> </div>
結果:
(2)
<div style="position:relative; z-index:0;"> <img src="./cat.jpg" style="position:absolute; z-index:2;" class="cat"> </div> <div style="position:relative; z-index:0;"> <img src="./dog.jpg" style="position:relative; z-index:1;" class="dog"> </div>
結果:
緣由:
z-index 值是auto,是一個普通元素,兩個img層比較不受父級的影響,按照規則誰大誰上,因而,z-index爲2的貓覆蓋值爲1的狗
z-index:0會建立一個層疊上下文。此時,層疊規則就發生了變化。層疊上下文特性裏最後一條規則,每一個層疊上下文都是獨立的。兩個img的層疊順序比較變成了優先比較其父級層疊上下文元素的層疊順序。因爲二者都是z-index:0,同樣大,此時,遵循層疊規則後來居上,根據在DOM出現的前後順序決定誰在上面,因而,位於後面的狗覆蓋貓。此時img元素上的z-index是沒有任何意義的。
E6/IE7瀏覽器有個bug,就是z-index:auto的定位元素也會建立層疊上下文。
(3) CSS3下的層疊上下文
CSS3的一些新屬性,會建立局部的層疊上下文,而且transform屬性會改變絕對定位的字元素的包含塊。
如下幾種狀況會產生新的層疊上下文:
1.z-index值不爲auto的flex項(父元素display:flex|inline-flex).
2.元素的opacity值不是1.
3.元素的transform值不是none.
4.元素mix-blend-mode值不是normal.
5.元素的filter值不是none.
6.元素的isolation值是isolate.
7.will-change指定的屬性值爲上面任意一個。
8.元素的-webkit-overflow-scrolling設爲touch.
display:flex|inline-flex與層疊上下文
須要知足兩個條件才能造成層疊上下文:
(1) 父級須要是display:flex/inline-flex
(2) 子元素的z-index不是auto,必須是數值。
此時,這個子元素爲層疊上下文元素,沒錯,注意了,是子元素,不是flex父級元素
demo:
<div class="box"> <div> <img src="./dog.jpg" class="dog"> </div> </div> .box div { width: 300px; height: 300px; background-color: pink; z-index: 101; } .box div img { width: 400px; height: 200px; position: relative; z-index: -1; }
結果:
緣由:此時的div是一個普通的元素,它上面設置的z-index是無效的,img的負值z-index會被塊級元素所遮擋。
接上:
.box { display: flex; }
結果:
div加上flex值以後,此時的z-index就會生效,會使它的子元素既內部的div造成層疊上下文。根據7層的層疊順序,background的那層會被負的z-index的那層所遮擋。
flex的出現打破了傳統的z-index必須與定位的元素一塊兒使用纔會生效的觀念。
opacity與層疊上下文
<div> <img src="./dog.jpg" class="dog"> </div> div { width: 300px; height: 300px; background-color: pink; } div img { width: 400px; height: 200px; position: relative; z-index: -1; }
結果:
給div加一個opacity的屬性:
div { width: 300px; height: 300px; background-color: pink; opacity: 0.5; /* 添加opcity屬性 */ }
只要設置的opacity的值不是1,就會造成層疊上下文。
表現結果:
transform對層疊上下文的影響
同上,對外層的div設置transform: rotate(15deg),會造成層疊上下文,致使圖片顯示在div的上面。
transform除了創建局部的層疊上下文還會改變絕對定位(固定定位也是絕對定位的一種)子元素的包含塊,
包含塊的概念:一些盒子根據它外面的矩形盒子計算獲得自身的定位和大小,這個外層的矩形盒子就是包含塊。
對固定定位的元素的影響:
正常的固定定位的包含塊是視口,加了transform就不同了
<div id="transform"> <div id="fixed"></div> </div> div { width: 100px; height: 100px; } #fixed { position: fixed; width: 100%; height: 100%; top: 0; left: 0; background: blue; } #transform { background: red; padding: 20px; }
fixed將會鋪滿整個屏幕。
結果:
上面加上
#transform { transform: scale(1); }
結果:
緣由,fixed的包含塊再也不是視口,而是transform這個div最邊緣。因此fixed的寬高均爲140px
對絕對定位的元素的影響:
<div id="relative"> <div id="transform"> <div id="absolute"></div> </div> </div> #relative { position: relative; width: 100px; height: 100px; background: green; } #absolute { position: absolute; width: 100%; height: 100%; top: 0; left: 0; background: blue; } #transform { background: red; width: 50px; height: 50px; }
此時absolute的包含塊爲relative的內邊距盒的邊緣盒。因此absolute的寬高是100px
給transform div加上transform屬性
結果:
因爲transform建立了局部層疊上下文,absolute的包含塊再也不是 relative而是transform了,根據這一新的包含塊,得新寬和高爲50px。
只要是有了transform這個屬性不論它的值是什麼都會影響絕對定位的子包含塊。
總結 :
層疊上下文的元素的層疊順序在哪一層:
依賴z-index值的元素,根據z-index的值來決定。
不依賴z-index的值的元素,它們的z-index的auto值至關於z-index:0級別。
第二種狀況解釋了爲何定位的元素會覆蓋掉普通流中的元素。定位的元素,會默認加上z-index: auto,按照7種層疊順序,會遮蓋普通流的元素。
當z-index的值同是auto,就是說層疊上下文的元素和定位的元素處於同一個層疊順序時,當她們發生重疊時,後面的元素會遮蓋上面的元素:
<img src="./dog.jpg" style="opacity: 0.5" class="dog"> <img src="./cat.jpg" style="position:relative; margin-left:-100px;" class="cat">
上面的元素調換位置:
<img src="./cat.jpg" style="position:relative; margin-left:-100px;" class="cat"> <img src="./dog.jpg" style="opacity: 0.5" class="dog">
z-index本質上仍是誰大誰在上面,雖然css3新加的一些屬性使z-index變的複雜,最多見的影響可能就是flex佈局致使的,可是規則仍是按照7種層疊順序來排布。