在我看來,z-index
給了咱們平常工做中以極大的幫助,咱們用它來定義元素的層疊級別(stack level)。受益於它,你能作Popup, DropDown, Tips, 圖文替換等等。css
在開始本篇以前,或許咱們要先了解一下關於z-index的基本信息。瀏覽器
每一個元素都具備三維空間位置,除了水平和垂直位置外,還能在 「Z軸」 上層層相疊、排列。元素在 「Z軸」 方向上的呈現順序,由層疊上下文和層疊級別決定。網絡
在文檔中,每一個元素僅屬於一個層疊上下文。元素的層疊級別爲整型,它描述了在相同層疊上下文中元素在 「Z軸」 上的呈現順序。性能
同一層疊上下文中,層疊級別大的顯示在上,層疊級別小的顯示在下,相同層疊級別時,遵循後來居上的原則,即其在HTML文檔中的順序。測試
不一樣層疊上下文中,元素呈現順序以父級層疊上下文的層疊級別來決定呈現的前後順序,與自身的層疊級別無關。字體
z-index: auto | <integer>
z-index
接受的屬性值爲:關鍵字auto和整數,整數能夠是負值(Firefox2.0及以前不支持負值)。url
須要注意的是 z-index
雖然很給力,卻只能應用於定位元素(即設置了 position
屬性爲非 static
值),其它狀況下,z-index
將被忽略。spa
對於定位元素而言,z-index
意味着:code
在規範中說明:當某個元素的 z-index
未顯式定義或者被指定爲 auto
時,該元素不會產生新的局部層疊上下文。也就是說它能夠和兄弟,祖先,後輩元素處在同一個堆疊上下文中,它們被放在一塊兒比較層疊級別,兒子能夠蓋住祖先,父親也能夠蓋住兒子,兒子甚至能夠越過祖先,蓋住祖先的兄弟,在層疊上下文中,它們是並級的關係。來看這樣一個例子 DEMO1
: z-index與建立層疊上下文orm
值得高興的是,大部分瀏覽器都實現了這個特性;不過在IE6/7下,不論 z-index
值是否被顯式定義,都將產生新的局部層疊上下文,也就是說子元素不能夠越過是定位元素的父親,子元素都處在新建立的局部層疊上下文中,只能在內部進行層疊級別的比較。
某區域內有個浮層提示或者下拉菜單,因而可能須要遮住該區域之下的區域。
<div class="a"> ... <div class="tips">我是一個簡陋的浮層提示</div> </div> <div class="b"> ... </div>
.a{position:relative;} .tips{position:absolute;z-index:99;}
如上HTML/CSS代碼,很顯然,浮層 tips
將能夠覆蓋在其父級元素 a
的兄弟元素 b
之上。
因而你的意圖獲得實現,效果以下 圖一
:
這是具體的實現例子 DEMO2
: z-index實現元素層疊。
不過很顯然,從 DEMO2
來看,你依然沒法準確的判斷出在各瀏覽器下,tips
能蓋住 b
是由於其父級的定位仍是自己的定位。
可是咱們能夠作這樣一個測試,咱們讓 b
也擁有定位,Code以下:
.a{position:relative;} .tips{position:absolute;z-index:99;} .b{position:relative;}
這段代碼run完以後,就比較糾結了,你能獲得的效果將會以下 圖二
:
固然要給出具體實現 DEMO3
: 驗證建立局部層疊上下文。
首先,咱們來解讀一下這個例子:由於 a
和 b
都是 relative
且沒有定義 z-index
(等同於z-index:auto),根據後來居上的原則,此時 b
的層疊級別是要高於 a
的,意思就是說 a
是沒法遮住 b
的。不過從 DEMO3
中,咱們看到 a
的子元素 tips
遮住了 b
,這就表示 tips
能越過它,因此能夠判斷出 a
沒有建立新的局部層疊上下文。很明顯,這是徹底吻合標準對此的定義。
不過這是在非IE6/7之下結果。在IE6/7下,咱們看到 tips
並沒能遮住 b
,也就是說 tips
沒法越過父級,由於 a
建立了新的局部層疊上下文,而 a
的層疊級別又比 b
低,因此 tips
沒法遮住 b
,這也就是在IE6/7下常出現覆蓋Bug的根源。
結合 DEMO2
和 DEMO3
,你能很確定的得出如下結論:
在實際工做中,有些狀況多是你沒注意或者已然存在的。好比你事先可能並不知道 b
也是定位元素,或者因爲某些緣由,你須要將其設置爲定位元素,因而可能出現各類兼容問題。若是你不瞭解 z-index
是如何建立局部層疊上下文,且又沒注意到IE6/7的實現錯誤,那麼處理起這樣的問題將會讓你深陷泥潭。
因此在實際的場景中,若是是爲了相互覆蓋而設置爲定位,那麼顯式的定義 z-index
值,將可避免出現建立新局部層疊上下文差別。
若是須要越過祖先和其它區塊內部元素進行相互層疊,那麼考慮IE6/7的狀況,也應該儘可能避免給父級元素進定位。
咱們知道 opacity
屬性是用來設置元素不透明度的。但可能知道 opacity
和層疊上下文有關的很少,不過不要緊,這裏咱們簡單聊聊這個話題,有兩點必須注意:
簡單來講,當一個普通的元素定義了 opacity
的值小於1時(好比 opacity:.5),那麼該元素的層疊級別將會高於普通元素,其效果類同於定位元素沒有顯式定義 z-index
的狀況,惟一的區別是沒有顯式定義 z-index
的定位元素不會產生局部層疊上下文,而定義了 opacity
值小於1的元素會產生新的局部層疊上下文。
假定咱們有 a
, b
, c
三個元素,它們相互層層覆蓋在一塊兒,若是這時將 a
元素定義爲 opacity:.8
,你知道結果會怎樣嗎?
<div class="a">a</div> <div class="b">b</div> <div class="c">c</div>
.a,.b,.c{width:100px;height:100px;} .a{opacity:.8;background:#999;} .b{margin:-70px 0 0 30px;background:#090;} .c{margin:-70px 0 0 60px;background:#f00;}
若是你看明白了我對於 opacity
與層疊上下文的描述,相信你能夠猜到結果,是的,a
元素將會覆蓋 b
和 c
元素,雖然它在HTML文檔中出如今 b
和 c
以前,且不是定位元素。
必須看看具體的示例不是麼?DEMO4
: opacity與局部層疊上下文猜測。
若是咱們將 b
和 c
設置爲定位元素,又將會如何呢?
.a,.b,.c{width:100px;height:100px;} .a{opacity:.8;background:#999;} .b{position:relative;margin:-70px 0 0 30px;background:#090;} .c{position:relative;margin:-70px 0 0 60px;background:#f00;}
不急,咱們能夠接着看示例 DEMO5
: opacity與局部層疊上下文猜測2。
從 DEMO4
和 DEMO5
兩例,咱們能夠驗證:當一個普通元素定義了 opacity
爲小於1的值時,該元素將像定位元素同樣擁有層疊級別,能夠覆蓋普通元素,而且其層疊級別與未顯式定義 z-index
的定位元素同樣。
與未顯式定義 z-index
的定位元素惟一不一樣的是 opacity
值小於1的元素會建立局部層疊上下文。
建立局部層疊上下文意味着什麼,前文咱們已經詳述過。因此再也不贅述,這裏只給一個示例用以驗證該特性。先奉上代碼:
<div class="a">a <div class="d">d</div> </div> <div class="b">b</div> <div class="c">c</div>
.a,.b,.c,.d{width:100px;height:100px;} .a{opacity:.8;background:#999;} .b{position:relative;margin:-70px 0 0 30px;background:#090;} .c{position:relative;margin:-70px 0 0 60px;background:#f00;} .d{position:absolute;z-index:99;height:50px;background:#090;}
你能夠先看看具體結果 DEMO6
: opacity建立新局部層疊上下文。
你會發現雖然 a
的子元素 d
將 z-index
定義爲99,但 d
仍然沒法遮住 b
和 c
元素,這是由於 a
建立了新的局部層疊上下文,d
元素沒法超越父級。
須要注意的是,此時就算 a
元素變成了定位元素,也不能改變其會建立新局部層疊上下文的命運,由於他設置了 opacity:.8
。
按照咱們前文所說,若是 a
沒有定義 opacity:.8
,但卻像 b
和 c
元素同樣設置了 relative
,那麼其子元素 d
將能夠覆蓋 b
和 c
,至於這個例子就再也不奉上了,你們隨便寫個測試一下便可。
上述都是理論性的東西,相對枯燥,來個實際點的應用場景。
咱們聊聊圖文替換的事,相對於使用較廣的方案如:縮進正/負值(正/負text-indent)、超小字體、margin溢出、padding溢出、line-height溢出、透明字體、display:none、visibility:hidden等方案而言,使用 z-index
負值的方案,有一些明顯的優點:
先來看看一個圖文替換的例子 DEMO7
: 圖文替換實例。
在不一樣的網絡環境下,它的表現以下 圖三
:
具體的Code很簡單:
<a href="#top" title="回到頂部"><span>TOP▲</span></a>
a,a span{display:inline-block;width:38px;height:38px;} a{background:url(images/ico.png) no-repeat;} a:hover{background-position:0 -39px;color:#fff;} a span{position:relative;z-index:-1;background-color:#eee;} a:hover span{background-color:#999;}
你會發現咱們將 span 設置爲了 z-index:-1
,此時它的層疊級別將比正常的元素還要低,因此它能夠被其父元素超連接a蓋住,從而在圖片正常載入時顯示父元素的背景圖,在網絡環境很差圖片載入有問題時,顯示自身。
不少時候,要實現一個需求可能有無數種解決方案,可以適應狀況越多的方案毫無疑問會脫穎而出,這就要求咱們能夠去更多的思考,而不是更多的拷貝。