前在項目的過程中遇到了一個問題,某個 div 希望始終顯示在最上面,而在之后的元素都顯示在它之下,當時設置了 z-index 也沒有效果,不知道什么原因,因此找了一下 CSS 相關資料,解決了這個問題的同時,也學習了很多知識,特此和大家分享一下。
屏幕是一個二維平面,然而 HTML 元素卻是排列在三維坐標系中, x 為水平方向, y 為垂直方向, z為屏幕由內向外方向,我們在看屏幕的時候是沿著 z 軸方向從外向內的。由此,元素在用戶視角就形成了層疊的關系,某個元素可能覆蓋了其他元素也可能被其他元素覆蓋;
這里有幾個重要的概念:層疊上下文 (堆疊上下文, Stacking Context)、層疊等級 (層疊水平, Stacking Level)、層疊順序 (層疊次序, 堆疊順序, Stacking Order)、z-index、BFC(塊級格式化上下文,Block Formatting Context),這些概念共同決定了你看到元素的位置,下面我們就圍繞著這幾個概念來一起學習一下。
聲明:
1. 層疊上下文 (Stacking Context)
層疊上下文 (堆疊上下文, Stacking Context),是 HTML 中一個三維的概念。在 CSS2.1 規范中,每個元素的位置是三維的,當元素發生層疊,這時它可能覆蓋了其他元素或者被其他元素覆蓋;排在 z 軸越靠上的位置,距離屏幕觀察者越近。
文章 <關于z-index 那些你不知道的事> 有一個很好的比喻,這里引用一下;
可以想象一張桌子,上面有一堆物品,這張桌子就代表著一個層疊上下文。如果在第一張桌子旁還有第二張桌子,那第二張桌子就代表著另一個層疊上下文。現在想象在第一張桌子上有四個小方塊,他們都直接放在桌子上。在這四個小方塊之上有一片玻璃,而在玻璃片上有一盤水果。這些方塊、玻璃片、水果盤,各自都代表著層疊上下文中一個不同的層疊層,而這個層疊上下文就是桌子。
每一個網頁都像一個房間,這個房間就是 <html></html>,其他層疊上下文就像這個房間里的桌子,HTML 標簽中的一切都被置于這個房間中。
當給一個元素的 position 值賦為 fixed 或 sticky 值時,你就創建了一個新的層疊上下文,其中有著獨立于頁面上其他層疊上下文和層疊層的層疊層,這就相當于你把另一張桌子帶到了房間里。
層疊上下文 1 (Stacking Context 1)是由文檔根元素形成的, 層疊上下文 2 和 3 (Stacking Context 2, 3) 都是層疊上下文 1 (Stacking Context 1) 上的層疊層。他們各自也都形成了新的層疊上下文,其中包含著新的層疊上下文。
在層疊上下文中,其子元素按照上面解釋的規則進行層疊。形成層疊上下文的方法有:
總結:
2. 層疊等級 (Stacking Level)
層疊等級 (層疊水平, Stacking Level) 決定了在同一個層疊上下文中,元素在 z 軸上的顯示的順序;
對于普通元素的層疊水平探討只局限于在當前層疊上下文中:
層疊上下文本身是一個強力的「層疊結界」,普通的元素水平是無法突破這個結界和結界外的元素去較量層疊水平的。
— CSS 世界
另外,層疊等級并不一定由 z-index 決定,只有定位元素的層疊等級才由 z-index 決定,其他類型元素的層疊等級由層疊順序、他們在 HTML 中出現的順序、他們的祖先元素的層疊等級一同決定,詳細的規則見下面層疊順序的介紹。
3. z-index
在 CSS 2.1 中, 所有的盒模型元素都處于三維坐標系中。除了我們常用的橫坐標和縱坐標, 盒模型元素還可以沿著「z 軸」層疊擺放,當他們相互覆蓋時,z 軸順序就變得十分重要。
-- CSS 2.1 Section 9.9.1 - Layered presentation
z-index 只適用于定位的元素,對非定位元素無效,它可以被設置為正整數、負整數、 0、 auto,如果一個定位元素沒有設置 z-index,那么默認為 auto;
元素的 z-index 值只在同一個層疊上下文中有意義。如果父級層疊上下文的層疊等級低于另一個層疊上下文的,那么它 z-index 設的再高也沒用。所以如果你遇到 z-index 值設了很大,但是不起作用的話,就去看看它的父級層疊上下文是否被其他層疊上下文蓋住了。
4. 層疊順序 (Stacking Order)
層疊順序 (層疊次序, 堆疊順序, Stacking Order) 描述的是元素在同一個層疊上下文中的順序規則(之前的層疊上下文和層疊等級是概念),從層疊的底部開始,共有七種層疊順序:
第 7 級順序的元素會顯示在之前順序元素的上方,也就是看起來覆蓋了更低級的元素:
除層疊順序優先級規則之外,還有一條后來居上規則:同一個層疊順序的元素按照在 HTML 里出現的順序依次層疊。這兩個規則共同決定瀏覽器元素在文檔中是如何層疊的。
5. 文檔流 (Document Flow)
5.1 常規流 (Normal flow)
5.2 浮動 (Floats)
5.3 絕對定位 (Absolute positioning)
6. BFC (Block Formatting Context)
6.1 什么是 BFC
BFC (Block Formatting Context) 塊級格式化上下文,是用于布局塊級盒子的一塊渲染區域,相對應的還有 IFC(Inline Formatting Context)內聯格式化上下文,不是本文重點,讀者可以自行查閱相關知識。
BFC 是 Web 頁面 CSS 視覺渲染的一部分,用于決定塊盒子的布局及浮動相互影響范圍的一個區域。
— MDN - 塊格式化上下文
一個 BFC 的范圍包含創建該上下文元素的所有子元素,但不包括創建了新 BFC 的子元素的內部元素。這從另一方角度說明,一個元素不能同時存在于兩個 BFC 中。因為如果一個元素能夠同時處于兩個 BFC 中,那么就意味著這個元素能與兩個 BFC 中的元素發生作用,就違反了 BFC 的隔離作用。
觸發 BFC 的方式有:
注意: display:table 也可以生成 BFC 的原因在于 Table 會默認生成一個匿名的 table-cell,是這個匿名的 table-cell 生成了 BFC。
6.2 用法
1. 阻止相鄰元素的 margin 合并
屬于同一個 BFC 的兩個相鄰塊級子元素的上下 margin 會發生重疊,(設置 writing-mode:tb-rl時,水平 margin 會發生重疊)。所以當兩個相鄰塊級子元素分屬于不同的 BFC 時可以阻止 margin 重疊。可以給任一個相鄰塊級盒子的外面包一個 div,通過改變此 div 的屬性使兩個原盒子分屬于兩個不同的 BFC,以此來阻止 margin 重疊。
代碼和預覽參見:Codepen - 使用BFC阻止margin合并:https://codepen.io/SHERlocked93/pen/eVOevN
2. 阻止元素被浮動元素覆蓋
一個正常文檔流的塊級元素可能被一個 float 元素覆蓋,擠占正常文檔流,因此可以設置一個元素的 float、 display、 position 值等方式觸發 BFC,以阻止被浮動盒子覆蓋。
代碼和預覽參見:Codepen - 使用BFC阻止元素被浮動元素覆蓋:https://codepen.io/SHERlocked93/pen/pazdzB
3. 包含浮動元素
通過改變包含浮動子元素的父盒子的屬性值,觸發 BFC,以此來包含子元素的浮動盒子。
代碼和預覽參見:Codepen - 使用BFC包含浮動元素:https://codepen.io/SHERlocked93/pen/OQLOqG
7. 實戰
下面一起來看幾個例子實戰一下,幫助理解。
7.1 普通情況
三個 relative 定位的 div 塊中各有 absolute 的不同顏色的 span.red、 span.green、 span.blue,它們都設置了 position:absolute;
代碼和預覽參見:Codepen - 普通情況:https://codepen.io/SHERlocked93/pen/aaPord
那么當沒有元素包含 z-index 屬性時,這個例子中的元素按照如下順序層疊(從底到頂順序):
紅綠藍都屬于 z-index 為 auto 的定位元素,因此按照 7 層層疊順序規則來說同屬于層疊順序第 6 級,所以按 HTML 中的出現順序層疊:紅->綠->藍
7.2 在相同層疊上下文的父元素內的情況
紅綠位于一個 div.first-box 下,藍位于 div.second-box 下,紅綠藍都設置了 position:absolute, first-box 與 second-box 都設置了 position:relative;
代碼和預覽參見:Codepen - 父元素不同但都位于根元素下:https://codepen.io/SHERlocked93/pen/RYENBw
這個例子中,紅藍綠元素的父元素 first-box 與 second-box 都沒有生成新的層疊上下文,都屬于根層疊上下文中的元素,且都是層疊順序第 6 級,所以按 HTML 中的出現順序層疊:紅->綠->藍
7.3 給子元素增加 z-index
紅綠位于一個 div.first-box 下,藍黃位于 div.second-box 下,紅綠藍都設置了 position:absolute,如果這時給綠加一個屬性 z-index:1,那么此時 .green 位于最上面;
如果再在 .second-box 下 .green 后加一個絕對定位的 span.gold,設置 z-index:-1,那么它將位于紅綠藍的下面;
代碼和預覽參見:Codepen - 設置了z-index:https://codepen.io/SHERlocked93/pen/gdZOrK
這個例子中,紅藍綠黃元素的父元素中都沒有生成新的層疊上下文,都屬于根層疊上下文中的元素
所以這個例子中的從底到高顯示的順序就是:黃->紅->藍->綠
7.4 在不同層疊上下文的父元素內的情況
紅綠位于一個 div.first-box 下,藍位于 div.second-box 下,紅綠藍都設置了 position:absolute,如果 first-box 的 z-index 設置的比 second-box 的大,那么此時無論藍的 z-index 設置的多大 z-index:999,藍都位于紅綠的下面;如果我們只更改紅綠的 z-index 值,由于這兩個元素都在父元素 first-box 產生的層疊上下文中,此時誰的 z-index 值大,誰在上面;
代碼和預覽參見:Codepen - 不同層疊上下文的父元素:https://codepen.io/SHERlocked93/pen/gdZbOJ
這個例子中,紅綠藍都屬于設置了 z-index 的定位元素,不過他們的父元素創建了新的層疊上下文;
所以這個例子中從低到到顯示的順序:藍->紅->綠
(我遇到的的情況就屬于這個例子類似情形)
7.5 給子元素設置 opacity
紅綠位于 div.first-box 下,藍位于 div.second-box 下,紅綠藍都設置了 position:absolute,綠設置了 z-index:1,那么此時綠位于紅藍的最上面;
如果此時給 first-box 設置 opacity:.99,這時無論紅綠的 z-index 設置的多大 z-index:999,藍都位于紅綠的上面;
如果再在 .second-box 下 .green 后加一個 span.gold,設置 z-index:-1,那么它將位于紅綠藍的下面;
代碼和預覽參見:Codepen - opacity的影響:https://codepen.io/SHERlocked93/pen/GXPRWB
之前已經介紹了,設置 opacity 也可以形成層疊上下文,因此:
所以這個例子中從低到到顯示的順序:黃->紅->綠->藍
關注微信公眾號:安徽思恒信息科技有限公司,了解更多技術內容……
多學員在學習的過程中都遇到過這樣的問題:為什么老師講的我都能聽懂,然而做起來卻總是諸多問題?千鋒重慶校區老師告訴你,其實這是正常現象,誰也不能幾天就成為大師,你的實踐還太少了!練習多了,經驗多了,靜態網頁自然也就手到擒來。
靜態的網頁其實就是由兩部分組成,一個是底層結構HTML,另外一個就是負責修飾結構的CSS。其實書寫靜態網頁就像小時候過家家,首先得把需要的家庭成員找齊了,即首先考慮要做一個什么樣的網站,例如一個綜合類網站包括:搜索框、導航、文章類別模塊、文章標題以及一部分廣告板塊;一個博客主頁包括:導航、文章縮略、文章搜索、文章導航以及沒有顯示但可能會有的評論區。
寫頁面的時候是有劇本的,這個劇本指網頁設計圖,或者某個現有網頁,建議大家在模仿網上現有網頁的時候利用瀏覽器自帶的截圖功能,把整個完整的頁面截取下來,QQ瀏覽器,360瀏覽器都可以做到。這樣的優點在于可以利用PS自己一步步測量數據、切圖都做到親力親為,并且做到了頁面數據的精準度,而不是隨意的給數據,或者是利用瀏覽器的F12功能查看原網頁的數據。
按照設計好的劇本接著就可以找對應的成員了,例如百度網頁從上往下分為導航頭部、中間logo和表單、尾部二維碼和文字,相對來說頁面的整體布局是比較簡單的,當然還有很多不同類型的頁面,布局要復雜一些。
當看到一個網頁時,需要在腦海當中對頁面進行一個簡單的掃描,如果把頁面當成一張紙,要怎么樣從大到小一點點分割。當有了初步的認識之后,就可以把這些東西轉化成HTML結構,所有不同顏色的框框在寫的時候用的都是DIV。
從上往下,從大到小一點點先把某個模塊以不同的顏色色塊利用代碼堆積出來。保證大的模塊布局沒問題之后,在往里面放一些小的東西,比如圖片img、表單form input、文字、超鏈接a、列表ul li,這時候簡單的頁面結構就出來了。
接下來要把寫好的結構進行美化,不然頁面就會一團亂麻,沒有美感,而網頁當中潤色部分是用CSS來做的。這個環節需要更加細心,例如百度首頁導航紅色框整體在綠色框的右邊,需要給紅色框添加float:right;紅色框里面文字的字號大小,字體,字體顏色,水平間距,垂直間距都需要一點點寫。如果在寫的過程中遇見了問題,可以借助Chrome瀏覽器的調試功能,哪里錯了用箭頭點哪里,結構看左邊,CSS看右邊,看看CSS屬性有沒有顯示,有沒有劃掉,有沒有黃色報錯等等。
在做頁面時,需要大量的練習,才可以熟能生巧。一個頁面寫完之后,總結一下這個頁面在書寫過程中遇到了哪些問題,是怎么解決的,為什么這樣解決,深入思考這個模塊的這個效果可不可以用其他的方法來實現,以做到舉一反三。
千鋒重慶HTML5大前端培訓,配合實戰項目講解網站頁面布局,讓你從容應對HTML、CSS的學習,基礎打好了,才能更有信心面對之后的挑戰。
許多方法可以將HTML元素與CSS對齊,但是一起使用或單獨使用它們并不是那么容易。開發人員所面臨的困難之一就是試圖將元素集中在頁面中間。
因此,在本文中,我將展示一些最常用的方法,即通過使用不同的CSS屬性在水平和垂直方向上居中圖像。
讓我們開始使用3個不同的CSS屬性將圖像水平居中。
使圖像水平居中的第一種方法是使用text-align屬性。但是,僅當圖像位于塊級容器(例如<div>)內時,此方法才有效:
使圖像居中的另一種方法是使用margin:auto屬性(用于左邊距和右邊距)。但是,單獨使用margin:Auto將不適用于圖像。如果需要使用margin:auto,則還必須使用2個其他屬性。
margin-auto屬性對內聯級別的元素沒有任何影響。由于<img>標簽是一個內聯元素,因此我們需要先將其轉換為塊級元素:
其次,我們還需要定義寬度。因此,左右邊緣可以占用其余的空白空間并自動對齊,可以這樣解決問題(除非我們給出100%的寬度):
將圖像水平居中的第三種方法是使用display:flex。同樣,我們對容器使用text-align屬性,它也會使用display:flex。但是,僅使用display:flex是不夠的。容器還必須具有一個稱為justify-content的附加屬性。
justify-content屬性與display:flex一起使用,我們可以使用它水平放置圖像的中心。最后,圖像的寬度必須小于容器的寬度,否則,它會占用100%的空間,然后我們就無法對其進行集中化。
1、Display: Flex
對于垂直對齊,使用display:flex確實很有幫助。考慮到我們的容器的高度為800px,但圖像的高度僅為500px:
現在,在這種情況下,向容器中添加一行代碼(align-items:center)就可以了:
如果將align-items屬性與display:flex一起使用,就會將元素垂直放置。
2、位置:絕對和變換屬性
垂直對齊的另一種方法是一起使用position和transform屬性。這個有點復雜,所以讓我們一步一步地做。
步驟1:定義絕對位置
首先,我們將圖像的定位行為從靜態更改為絕對:
同樣,它應該位于相對放置的容器內,因此我們添加一個位置:相對于其容器的div。
步驟2:定義頂部和左側屬性
其次,我們定義圖像的頂部和左側屬性,并設置為50%。這會將圖像的起點(左上角)移到容器的中心:
步驟3:定義變換屬性
在第二步的時候已經將圖像的一部分移出容器。因此,我們需要將其取回內部。在圖像上定義轉換屬性,并在其X和Y軸上添加負50%可以達到目的:
還可以使用其他方法進行水平和垂直居中,我這里只嘗試了最常用的方法。希望這篇文章可以幫助你了解如何在頁面中心對齊圖像。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。