定位到元素后获取其属性_(11)让“盒子”动起来:② “定位”和 BFC | CSS
??????以下鏈接為本文最新勘誤篇章——《讓“盒子”動起來:② “定位”和 BFC》
上方面試題“參考答案詳解”,請點擊此處查看獲取方式!
前言: 這一篇我們主要探討“定位”和 BFC 是怎樣讓“盒子”動起來的。
學習方法依然是:打開 JS Bin,拷貝代碼運行查看效果,然后搞定每一行代碼的前世今生。
1 什么是“定位”
“定位”就是通過設置 position 屬性的值來脫離正常的文檔流。
2 “定位”分哪幾類
2.1 相對定位
源碼及效果展示
HTML
CSS
.box1, .box2 {width: 50px;height: 50px;border: 2px solid; } .box2 {position: relative;/*relative 是相對于它原本正常流的位置進行偏移,視覺上看它是移動了,但它原本所占用的文檔流的空間是沒有變化的,對其他元素來說,它還是在那里的,故其他元素位置是不會有變化的。*/top: 10px;left: 10px; }2.2 絕對定位
當你設置為絕對定位后,文檔流上的其他元素就看不見你了。就認為你不存在!如果存在多個絕對定位元素,那么這些絕對定位元素也互相看不見。
源碼及效果展示
HTML
CSS
.box1, .box2 {width: 50px;height: 50px;border: 2px solid; } .box2 {color: red;position: absolute;top: 10px;left: 10px;/*?這個值是相對于誰做偏移呢?答:首先它會從自己的父元素里邊去找,看看自己的父元素里邊有沒有定位,這個定位包括 relative、absolute、fix,如果有的話就相對于它;如果沒有的話,就再從父元素的父元素里邊去找,如果有的話就相對于它;如果再沒有,就一直找到我們的 body。*/ }2.2.1 ?絕對定位的值是相對誰來取值做偏移
源碼及效果展示
HTML
CSS
html {border: 3px solid blue;/* 3??最后,如果都沒有,那么 box2 的絕對定位值就相對于這里,到頭了。 */} body {margin: 40px;border: 1px solid red;/*2??其次,如果下邊 container 沒有 position,而這里有定位(relative、absolute、fixed),那么 box2 的絕對定位值就相對于這里:position: relative;*/ }container {margin-top: 40px;padding: 40px;background: yellow;/*1??首先,如果 box2 父元素這里有定位(relative、absolute、fixed),那么 box2 的絕對定位值就相對于這里:position: relative;??而這里用 relative 是最好的,因為一個元素本身設置 relative,卻不設置值的話,就等同于沒設置。那它就依然在普通流中,它還是一個普通元素,那它自己的位置也沒發生變動,卻可以給其子元素作為相對的錨點。*/ }.box1, .box2 {width: 50px;height: 50px;border: 2px solid; } .box2 {position: absolute;top: 0px;left: 10px; }/* ??所以,我們在使用絕對定位的時候,一定要設置好定位的參考點(錨點)。 一般來說,我們絕對定位的參考點都是相對于其父容器。所以原則上是:一個元素設置絕對定位 absolute, 那它的父容器設置定位為 relative。*/2.2.2 z-index
元素使用了絕對定位后,就如浮動一樣,有了“塊盒子”的特性。
由于使用絕對定位之后,產生元素覆蓋的問題,z-index 可以解決元素之間覆蓋順序的問題,設置它的層疊順序。同級元素,數值越大,越靠近視覺點;不同父元素,只要父元素越大,那么整體就越靠近視覺點,而不管其子元素大小情況。
- z-index: 顯示器顯示的圖案是一個二維平面,用 x 軸和 y 軸來表示位置屬性。
為了表示三維立體的概念,如顯示元素的上下層的疊加順序,引入了 z-index 屬性來表示 z 軸上一個元素在疊 加順序上的上下立體關系。
z-index 值較大的元素將疊加在 z-index 值較小的元素之上。對于未指定此屬性的定位對象,z-index 值為正數的對象會在其之上,而 z-index 值為負數的對象在其之下。
z-index 屬性適用于定位元素(position 屬性值為 relative 或 absolute 或 fixed 的對象),用來確定定位元素 在垂直于顯示屏方向(稱為 Z 軸)上的層疊順序,也就是說如果元素是沒有定位的,對其設置的 z-index 會是無效的。 - 相同 z-index 誰上誰下?
- 如果兩個元素都沒有定位發生位置重合現象或者兩個都已定位元素且 z-index 相同發生位置重合現象,那么按文檔流順序,后面的覆蓋前面的。
- 如果兩個元素都沒有設置 z-index,使用默認值,一個定位一個沒有定位,那么定位元素覆蓋未定位元素。
- 父子關系處理:
- 如果父元素 z-index 有效,那么子元素無論是否設置 z-index 都和父元素一致,會在父元素上方;
- 如果父元素 z-index 失效(未定位或者使用默認值),那么定位子元素的 z-index 設置生效。
2.3 固定定位
position: fixed;相對于瀏覽器的窗口進行定位。因此當滾動產生時,固定定位元素依然處于窗口的某個位置不動。
3 用“定位”還是用“浮動”
- 大布局、自適應,用“浮動”————浮動一般和響應式結合的比較多;
- 小元素、固定寬高,用“定位”————一般只適用于一些很小的 icon ;
結合實際情況是關鍵。
比如說,網頁頭像上的未讀消息,我們一般都是選擇用“定位”才能很好的實現。凡是能蓋住其他東西的也是“絕對定位”。
4 小實戰:實現 navbar
源碼及效果展示
HTML
CSS
* {margin: 0;padding: 0; } ul {list-style: none; } a {color: #333;text-decoration: none; } nav {width: 500px;margin: 10px auto 0;box-shadow: 0px 2px 4px 1px rgba(0,0,0,0.3);/*這里邊的這幾個值:第一、二個值表示這個陰影的水平、垂直的偏移;4px 表示模糊度;1px 是這個模糊的一個延展;rgba 是這個模糊的顏色。*/ } nav::after {content: '';display: block;clear: both; } /* 由于我們用了浮動,我們需要清除浮動來撐開父容器。 */nav>ul>li {position: relative;/* 給下邊 .child 的絕對定位”偏移值“加一個“錨點”。 */float: left;/* 把這個選擇器層級里的 li 水平排列。 */} nav>ul>li:hover .child {display: block; } /* .child 默認是隱藏的,當我鼠標放到“更多”這個 li 上的時候才顯示,并顯示為 block。 */nav a {display: block;padding: 10px 10px;/*記著,我們要想點擊的范圍很大,我們是需要在 a 鏈接上來加 padding 的。如果在 li 上加 padding,那么點擊范圍依然在字上。但要注意,由于 a 鏈接是個行內元素,所以如果這里只單單加 padding,那其實他的寬高是沒有變化的,只是背景色變大了,它會出現很多諸如“遮擋”的后果。故,我們需要讓其顯示為 block。我們沒有用 inline-block 是因為:用 inline-block 即它同時還是有行內特性,會導致"收縮"——即寬度由文本內容寬度決定。想要撐開,而不受內容寬度影響,那就需要用 block。*/min-width: 50px;/* 這里加了一個“最小的寬度”的用途是把這個 a 鏈接里邊的文字內容撐開,使任何一個可點擊的文本都不換行。*/ } nav a:hover {color: #fff;background: rgba(0, 0, 0, 0.4); } nav .child {position: absolute;/*設置了絕對定位,我們才可以想把這個 .child 放哪里就放哪里,因為父容器發現不了它。而其他方式(比如浮動、或不用)是達不到理想的效果的。*/top: 100%;/* 100% 就表示按照 li 的高度。 */box-shadow: 0px 2px 4px 1px rgba(0, 0, 0, 0.3);display: none;/*.child 默認是"隱藏"的——display: none; ,當我鼠標放到“更多”這個 li 上的時候再顯示。*/ }5 BFC
??相關前置知識,請先閱讀文章:
《CSS 基本視覺格式化:① “塊盒子”格式化》
《CSS 基本視覺格式化:② “行內盒子”格式化》
- 在正常流中,盒子要么屬于塊級格式化上下文,要么屬于內聯格式化上下文。
每個渲染區域用 fomating context 表示,它決定了其子元素如何去定位,以及和其他元素的關系和相互作用。
BFC 全稱 Block Formating Context。 - BFC 是一個獨立的渲染區域,只有 block-level box 參與。它規定了內部 block-level box 如何布局,并且與這個區域外部毫不相關。
5.1 哪些元素會具有 BFC 的條件
display 屬性為 block、list-item、table 的元素,會產生 BFC。也就是“塊元素”。
5.2 什么情況下可以讓元素產生 BFC
- float 屬性不為 none:
如果一個元素增加了一個屬性叫 float,那這個元素本身也產生了一個塊級格式化上下文。 - position 為 absolute 或 fixed ;
- display 為 inline-block、table-cells、flex、或者 inline-flex ;
- overflow 不為 visible (為 hidden、auto、scroll )。
我們之所以要了解這個 BFC,是因為我們希望通過了解它的特性來實現我們需要的一些效果。或者當出現了某個問題的時候,我們能夠去解釋這個問題,知道是為什么,進而解決它或找到替代方案。
5.3 BFC 布局規則特性
- ①:在 BFC 中,盒子從頂部開始垂直地一個接一個的排列;
- ②:盒子垂直方向的距離由 margin 決定,屬于同一個 BFC 的兩個相鄰盒子的 margin 會發生重疊;
- ③:在 BFC 中,每一個盒子的左外邊距應該和包含塊的左邊接觸(對于從左往右的格式化,否則相反)。即使存在浮動也是如此!
- ④:BFC 的區域不會與浮動的盒子產生交集,且是緊貼浮動的邊緣;
- ⑤:計算 BFC 的高度時,浮動盒子的高度也參與計算;
- ⑥:BFC 就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。反之也如此!
5.4 BFC 常見的用途
- 清除元素內部浮動
對應規則:⑤ 計算 BFC 的高度時,浮動盒子的高度也參與計算。 - 解決外邊距合并問題
對應規則:② 盒子垂直方向的距離由 margin 決定,屬于同一個 BFC 的兩個相鄰盒子的 margin 會發生重疊。 - 制作自適應兩欄布局
對應規則: ③ 在 BFC 中,每一個盒子的左外邊距應該和包含塊的左邊接觸(對于從左往右的格式化,否則相反)。即使存在浮動也是如此!
5.4.1 清除元素內部浮動
?問題:
源碼及效果展示
??解決方式:
- 通過“清除浮動”來解決——在文章《讓盒子動起來:①浮動》中已作解答;
- 通過給父元素創建 BFC,添加 overflow: hidden; 樣式:
源碼及效果展示
<ul class="navbar"><li><a href="#">1 首頁</a></li><li><a href="#">2 產品</a></li><li><a href="#">3 服務</a></li><li><a href="#">4 關于</a></li> </ul> .navbar {list-style: none;border: 1px solid #ccc;overflow: hidden; } .navbar>li {float: left;margin-left: 15px; }5.4.2 解決外邊距合并問題
?問題:
在文章《CSS 基本視覺格式化:① 塊盒子格式化》中,我們知道:
??注意:當一個元素包含在另一個元素中時,彼此相鄰的 margin-bottom 和 magin-top 也會發生疊加,取較大者。
源碼及效果展示
<div class="box1">1</div> <div class="box2">2</div> .box1 {color: #fff;width: 100px;height: 100px;margin-bottom: 50px;background: blue; }.box2 {color: #fff;width: 100px;height: 100px;margin-top: 100px;background: pink; }??解決方式:
將垂直方向上的盒子放在不同的 BFC 中,margin 就不會重疊了。
源碼及效果展示
<div class="box1">1</div><div class="ct"><div class="box2">2</div> </div> <!-- 我們在 box2 的外層包裹一層容器,并觸發該容器生成一個 BFC。 那么兩個 box 就不屬于同一個 BFC,就不會發生 margin 重疊了! --> .ct {overflow: hidden; /* 觸發該容器生成一個 BFC */ }.box1 {color: #fff;width: 100px;height: 100px;margin-bottom: 50px;background: blue; }.box2 {color: #fff;width: 100px;height: 100px;margin-top: 100px;background: pink; }5.4.3 制作自適應兩欄布局
?問題:
在文章《讓“盒子”動起來:① 浮動》中,我們通過加 margin-left 或 margin-right 的方式制作“有縫隙”的兩欄布局的效果。
??但如果要求兩欄布局中間沒有縫隙,該怎么辦呢?
?由于:
③ 在 BFC 中,每一個盒子的左外邊距應該和包含塊的左邊接觸(對于從左往右的格式化,否則相反)。即使存在浮動也是如此!源碼及效果展示
<div class="aside">側邊欄固定寬度</div> <div class="main">Hey guys,我正在這個平臺發放“前端一萬小時”這個專欄的一系列文章。<br>這個專欄我已經完成了“從零基礎到就業”相關的文章。<br>"從零基礎到就業"包含 150+ 篇干貨文章,300+ 道經典筆試、面試題。<br>如果你對本系列文章感興趣,歡迎關注 「公眾號:前端一萬小時」,并點擊菜單欄“輕松入職”來加入我們的“一萬小時計劃”!祝順利^^…… </div> .aside {color: #fff;width: 150px;height: 100px;background: red;float: left; } .main {color: #fff;background: blue;height: 200px; }??解決方式:
④ BFC 的區域不會與浮動的盒子產生交集,且是緊貼浮動的邊緣。通過觸發 main 生成 BFC,來實現自適應無縫隙兩欄布局:
源碼及效果展示
.main {overflow: hidden; /* 觸發 BFC */ }.aside {color: #fff;width: 150px;height: 100px;background: red;float: left; } .main {color: #fff;background: blue;height: 200px; }后記: 通過兩篇兄弟文章,我們算是讓“盒子”動了起來。接下來 3 篇文章,我們就讓“這個可以動的盒子”更優雅的“展示”。
祝好,qdywxs ? you!
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的定位到元素后获取其属性_(11)让“盒子”动起来:② “定位”和 BFC | CSS的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Effective Java2》笔录
- 下一篇: 在EA中画ER图和数据模型图