《CSS世界》筆記五:CSS層疊規則及元素隱藏

上一篇:《CSS世界》筆記四:流的保護與破壞css

寫在前面

《CSS世界》這本書還剩六章,可是這本書的精華部分主要是前面的內容,這裏僅把後面章節相對重要的內容以博客展現,想着瞭解更多的小夥伴仍是去閱讀原文的好,畢竟三百多頁的一本書並非小小几篇博客能徹底說清楚的。html

這個也算是《CSS世界》讀書筆記系列博客的終結篇了,雖然說是「二進宮」,收穫依然滿滿,畢竟好書每次讀都能讀出新東西。這裏仍是要吐槽幾句,前端崗位不少同窗(確定不包括帥氣的你啦!)都不過重視CSS,不就是佈局嗎,記幾條屬性也就可以實現一個網頁佈局,可是正是這些同窗,每每在作適配和頁面調整時抱怨不斷,或者在調整時幾乎就是重構,CSS代碼絲毫沒有健壯性可言,熟不知合理使用CSS屬性和健壯佈局能爲你省不少事,甚至可以爲你省去不少js代碼。這裏彷佛寫出了「CSS重要性」的論斷,哈哈!前端

1、CSS世界的層疊規則

聲明:CSS中並不僅是z-index可以決定元素的z軸順序。web

1.1 元素層疊順序(stacking level)

圖片描述

補充說明:segmentfault

  1. 位於最下面的 background/border 特指層疊上下文元素(後面會詳解)的邊框和背景色。每個層疊順序規則僅適用於當前層疊上下文元素的小世界;
  2. inline水平盒子指的是包括inline/inline-block/inline-table元素的「層 疊順序」,它們都是同等級別的;
  3. 單純從層疊水平上看,實際上 z-index:0 和 z-index:auto 是能夠當作是同樣的,實際上,二者在層疊上下文領域有着根本性的差別

記憶要訣:佈局

  1. 因爲網頁是圖文展現爲主,inline會高於標準流盒子和浮動盒子
  2. 元素一旦成爲定位元素,其 z-index 就是默認的 auto,根據上面的層疊順序表,就會覆蓋 inline 或 block 或 float 元素

1.2 層疊上下文(stacking context)

層疊上下文是一個概念,跟「塊狀格式化上下文」 (BFC)相似。然而,概念這個東西是比較虛、比較抽象的,要想輕鬆理解,咱們須要將其具象化。

怎麼個具象化法呢?咱們能夠把層疊上下文理解爲一種「層疊結界」,自成一個小世界。界中可能有其餘的「層疊結界」,而自身也可能處於其餘「層疊結界」中。flex

如何建立層疊上下文動畫

(1)天生派:頁面根元素天生具備層疊上下文,稱爲根層疊上下文(html標籤)spa

(2)正統派:z-index 值爲數值的定位元素的傳統「層疊上下文」code

對於position值爲relative/absolute以及Firefox/IE(不包括Chrome)下含有position:fixed聲明的定位元素,當其z-index值不是auto的時候,會建立層疊上下文

(3)擴招派:CSS3屬性建立

  1. 元素爲flex佈局元素(父元素display:flex | inline-flex),同時z-index值不是auto
  2. 元素的opacity值不是1
  3. 元素的transform值不是none
  4. 元素mix-blend-mode值不是normal
  5. 元素的filter值不是none
  6. 元素的isolation值是isolate
  7. 元素的will-change屬性值爲上面2~6的任意一個(如will-change: opacity、will-chang:transform等)
  8. 元素的-webkit-overflow-scrolling設爲touch

CSS3建立層疊上下文引證

<!-- 2在1之上 -->
<img src="1.jpg" style="position:relative">
<img src="2.jpg" style="transform:scale(1);">

<!-- 1在2之上 -->
<img src="2.jpg" style="transform:scale(1);">
<img src="1.jpg" style="position:relative">

因爲層疊問題引起的bug:

描述:有一個絕對定位的黑色半透明層覆蓋在圖片上。可是,一旦圖片開始走 fadeIn 淡出的 CSS3 動畫,文字就跑到圖片後面去了,由於文字一直是 100%透明的純白色,文字變淡是由於跑到圖片後面,而圖片半透明,文字穿透顯示而已

緣由:fadeIn 動畫本質是 opacity 透明度的變化,「元素的opacity值不是1」時會建立層疊上下文,爲1時爲普通元素。致使層級發生變化時引起bug

圖片描述

1.3 層疊黃金準則(重點)

(1)誰大誰上:當具備明顯的層疊水平標識的時候,如生效的 z-index 屬性值,在同一個層疊上下文領域,層疊水平值大的那一個覆蓋小的那一個

(2)後來居上:當元素的層疊水平一致、層疊順序相同的時候,在 DOM 流中處於後面的元素會覆蓋前面的元素

下面有兩個案例,請問兩種狀況的層疊順序:

<div style="position:relative; z-index:auto;">
    <img src="1.jpg" style="position:absolute; z-index:2;">
</div>
<div style="position:relative; z-index:auto;">
    <img src="2.jpg" style="position:relative; z-index:1;">
</div>
<div style="position:relative; z-index:0;">
    <img src="1.jpg" style="position:absolute; z-index:2;">
</div>
<div style="position:relative; z-index:0;">
    <img src="2.jpg" style="position:relative; z-index:1;">
</div>

答案:(1)1在上2在下;(2)1在下2在上

分析:z-index: auto所在的<div>元素是一個普通定位元素,因而,裏面的兩個<img>元素的層疊比較就不受父級的影響,二者直接套用「誰大誰上」的準則;而z-index一旦變成數值,哪怕是 0,就會建立一個層疊上下文。此時遵循「層疊黃金準則」的另一個準則「後來居上」,根據在DOM文檔流中的位置決定誰在上面

思考:在不居中層級錯亂時,能夠找找父級元素的層級與目標元素(或父級)層級比較

1.4 zIndex能夠爲負值

對照着上面的層疊順序圖,咱們能夠知道zIndex爲負值時是介於背景和普通流盒子之間的,直接看一個例子,請問下面的層疊狀況

/* 狀況一 */
<div class="father">
    <div class="son">son</div>
</div>

/* 狀況二 */
<div class="father transform">
    <div class="son">son</div>
</div>

.father {
    width: 200px;
    height: 200px;
    background-color: rgba(0, 0, 255, .7);
}
.son {
    position: relative;
    z-index: -1;
    width: 200px;
    height: 100px;
    background-color: rgba(255, 0, 0, .7);
}

.transform {
    margin-top: 20px;
    transform: scale(1);
}

圖片描述

分析:

狀況一:當.father是普通元素時,.son元素所在的層疊上下文元素一是.father的某個祖先元素;.son是 z-index 負值元素,.father是 block 元素,也就是.son應該在.father元素的後面顯示,所以,.son會被.father元素的藍色背景覆蓋;

狀況二:當.father是層疊上下文元素時,z-index 負值元素在層疊上下文元素的背景上,所以,.son.father元素的藍色背景上;

2、元素隱藏

2.1 元素各類隱藏方法

(1)若是但願元素不可見,同時不佔據空間,輔助設備沒法訪問,但資源有加載,DOM 可訪問,則能夠直接使用 display:none 隱藏

.dn { display: none; }

(2)若是但願元素不可見,同時不佔據空間,輔助設備沒法訪問,但顯隱的時候能夠有transition 淡入淡出效果

.hidden {
    position: absolute;
    visibility: hidden;
}

(3)若是但願元素不可見,不能點擊,輔助設備沒法訪問,但佔據空間保留,則可使用 visibility:hidden 隱藏

.vh { visibility: hidden; }

(4)若是但願元素不可見,不能點擊,不佔據空間,但鍵盤可訪問,則可使用 clip 剪裁隱藏

.clip {
    position: absolute;
    clip: rect(0 0 0 0);
}

(5)若是但願元素不可見,不能點擊,但佔據空間,且鍵盤可訪問,則能夠試試 relative 隱藏。例如,若是條件容許,也就是和層疊上下文之間存在設置了背景色的父元素, 則也可使用更友好的 z-index 負值隱藏

.lower {
    position: relative;
    z-index: -1;
}

(6)若是但願元素不可見,但能夠點擊,並且不佔據空間,則可使用透明度

.opacity {
    position: absolute;
    opacity: 0;
    filter: Alpha(opacity=0);
}

(7)若是單純但願元素看不見,但位置保留,依然能夠點能夠選,則直接讓透明度爲 0

.opacity {
    opacity: 0;
    filter: Alpha(opacity=0);
}

2.2 display與visiblity隱藏比較

空間佔據

display:none 隱藏後的元素不佔據任何空間

visibility:hidden 隱藏的元素空間依舊存在

後代隱藏原理

display屬性值爲none時,該元素以及全部後代元素都隱藏

visibility屬性值hidden時,子元素也會看不見,由於子元素繼承了visibility:hidden

所以,當子元素設置visibility:visible;時,子元素又會顯現

<ul style="visibility:hidden;">
    <li style="visibility:visible;">列表1</li>
    <li>列表 2</li>
    <li>列表 3</li>
    <li style="visibility:visible;">列表4</li>
</ul>

最終列表1和列表4依然會顯示

3、總結

  1. CSS層疊上下文理解和建立
  2. CSS層疊順序和規則
  3. 元素隱藏的各類方式及對比

上一篇:《CSS世界》筆記四:流的保護與破壞

相關文章
相關標籤/搜索