主要內(nèi)容: 浮動(dòng)的介紹、清除浮動(dòng)、各種定位、BFC以及外邊距合并的介紹。
浮動(dòng)
什么是浮動(dòng)元素
浮動(dòng)元素是float 的值不是none的元素。
浮動(dòng)元素的特征
- 任何元素都可以浮動(dòng)。浮動(dòng)元素會(huì)生成一個(gè)塊級(jí)框,而不論它本身是何種元素
- 浮動(dòng)元素會(huì)盡可能遠(yuǎn)地向左或者向右浮動(dòng), 直到它的外邊緣碰到包含框或者另外一個(gè)浮動(dòng)元素的框的邊緣
- 浮動(dòng)元素從網(wǎng)頁(yè)的正常流動(dòng)中移除,但是仍然保持部分的流動(dòng)性(與絕對(duì)定位相反)
- 由于浮動(dòng)元素從網(wǎng)頁(yè)的正常流中刪除, 所以會(huì)造成父容器塌陷
- 文本和內(nèi)聯(lián)元素會(huì)環(huán)繞浮動(dòng)元素。浮動(dòng)元素脫離普通流,如果浮動(dòng)元素后面有一個(gè)文檔流中元素, 那么這個(gè)元素的框會(huì)表現(xiàn)的像浮動(dòng)元素不存在, 但是框的文本內(nèi)容會(huì)受浮動(dòng)元素影響,會(huì)移動(dòng)以留出空間
浮動(dòng)元素對(duì)其他元素的影響
- 對(duì)父容器的影響:對(duì)于其父元素來(lái)說(shuō),元素浮動(dòng)之后,它脫離當(dāng)前正常的文檔流,所以它也無(wú)法撐開(kāi)其父元素,造成父容器的塌陷
- 對(duì)其他浮動(dòng)元素的影響:
同一個(gè)方向的浮動(dòng)元素:當(dāng)一個(gè)浮動(dòng)元素在浮動(dòng)過(guò)程中碰到同一個(gè)方向的浮動(dòng)元素時(shí),它會(huì)緊跟在它們后面;
反方向的浮動(dòng)元素:互不影響,位于同一條水平線上,當(dāng)空間不夠時(shí)會(huì)被擠下 - 普通元素的影響:
如果浮動(dòng)元素后面兄弟元素為塊級(jí)元素,該元素會(huì)忽視浮動(dòng)元素的而占據(jù)它的位置,但它的內(nèi)部文字和其他行內(nèi)元素都會(huì)環(huán)繞浮動(dòng)元素。
但是如果后面的塊元素設(shè)置了clear屬性時(shí), 會(huì)對(duì)塊元素產(chǎn)生影響, 具體情況取決于clear的值 - 對(duì)文字的影響:文字會(huì)環(huán)繞浮動(dòng)元素排列
清除浮動(dòng)
清除浮動(dòng)指什么
清除浮動(dòng)指元素的側(cè)邊不允許出現(xiàn)浮動(dòng)元素,從而使得浮動(dòng)元素的不占據(jù)普通文檔流空間的造成的父元素的高度塌陷問(wèn)題得到解決,主要通過(guò)clear屬性實(shí)現(xiàn)。
clear:指定一個(gè)元素是否可以在它之前的浮動(dòng)元素旁邊,或者必須向下移動(dòng)(清除浮動(dòng)) 在它的下面。clear 屬性適用于浮動(dòng)和非浮動(dòng)元素。
當(dāng)應(yīng)用于非浮動(dòng)塊時(shí),它將非浮動(dòng)塊的邊框邊界移動(dòng)到所有相關(guān)浮動(dòng)元素外邊界的下方。這個(gè)行為作用時(shí)會(huì)導(dǎo)致margin collapsing不起作用。
當(dāng)應(yīng)用于浮動(dòng)元素時(shí),它將元素的外邊界移動(dòng)到所有相關(guān)的浮動(dòng)元素外邊界的下方。這會(huì)影響后面浮動(dòng)元素的布局,后面的浮動(dòng)元素的位置無(wú)法高于它之前的元素。
方法:
- 設(shè)置浮動(dòng)包含塊的父元素height值。
- 使得含塊的父元素變成BFC。
- 通過(guò)添加:after偽元素,然后在偽元素上設(shè)置clear屬性來(lái)實(shí)現(xiàn)。
如何清除浮動(dòng)
清除浮動(dòng)之前,可以看到由于浮動(dòng)元素脫離了文檔流, 父元素塌陷了:

- 添加空的div,利用clear屬性清除浮動(dòng)
如果我們想讓父元素在視覺(jué)上包圍浮動(dòng)元素可以像下面這樣處理,在最后添加一個(gè)空div,利用clear屬性對(duì)它清理。缺點(diǎn)是增加了一個(gè)無(wú)意義的標(biāo)簽

- 利用BFC可以包含浮動(dòng)的特性讓父容器形成BFC,從而達(dá)到清除浮動(dòng)的目的 (具體怎么形成BFC后面會(huì)介紹)
使用BFC清除浮動(dòng)也有它的局限性:
使用float的時(shí)候會(huì)使父容器長(zhǎng)度縮短,而且有個(gè)重要缺陷:父容器float解決了其塌陷問(wèn)題, 那么父容器的父容器怎么辦;
overflow 屬性會(huì)影響滾動(dòng)條和絕對(duì)定位的元素;
position 會(huì)改變?cè)氐亩ㄎ环绞剑?br>
display這幾種方式?jīng)]有解決低版本IE的問(wèn)題……
- 最標(biāo)準(zhǔn),無(wú)副作用的清除浮動(dòng)的方法: 給需要清除浮動(dòng)的父元素加上以下代碼(IE6.7不支持 )
.clearfix:after{
content:' ';
display: block;
clear: both;
}
或者:
.clearfix:after{
content:' ';
display: table;
clear: both;
}
定位
CSS有三種基本的定位機(jī)制:普通流,浮動(dòng),絕對(duì)定位(absolute,fixed)
普通流
普通流是默認(rèn)定位方式,在普通流中元素框的位置由元素在html中的位置決定,這也是我們最常見(jiàn)的方式,其中position: static與position:relative屬于普通流的定位方式。
相對(duì)定位可以看作特殊的普通流定位,元素位置是相對(duì)于它在普通流中位置發(fā)生變化(即相對(duì)于元素本身正常位置進(jìn)行定位)。在使用相對(duì)定位時(shí),無(wú)論元素是否移動(dòng),元素在文檔流中占據(jù)原來(lái)空間 ,只是表現(xiàn)出來(lái)的位置會(huì)改變。
浮動(dòng)
設(shè)置了浮動(dòng)的元素會(huì)脫離普通流,它可以向左或者向右移動(dòng)直到它碰到了包含框或者另外一個(gè)浮動(dòng)的邊框。浮動(dòng)元素會(huì)對(duì)其他浮動(dòng)元素以及它后面的普通流中的文本產(chǎn)生影響。
絕對(duì)定位
絕對(duì)定位的元素的位置是相對(duì)于距離最近的非static祖先元素位置決定的。如果元素沒(méi)有已定位的祖先元素,那么他的位置就相對(duì)于初始包含塊html來(lái)定位。
絕對(duì)定位使元素的位置與文檔流無(wú)關(guān),也不占據(jù)文檔流空間,普通流中的元素布局就像絕對(duì)定位元素不存在一樣。
由于絕對(duì)定位與文檔流無(wú)關(guān),所以絕對(duì)定位的元素可以覆蓋頁(yè)面上的其他元素,可以通過(guò)z-index屬性控制疊放順序,z-index越高,元素位置越靠上。
絕對(duì)定位的寬度是收縮的。
絕對(duì)定位包括 absolute和 fixed。fixed固定定位,固定定位是絕對(duì)定位的一種,固定定位的元素也不包含在普通文檔流中,差異是固定元素的包含塊兒是視窗(viewport)
CSS position屬性
CSS屬性 position用于指定一個(gè)元素在文檔中的定位方式,position的值有以下種:
| 值 | 描述 |
|---|---|
| inherit | 從父元素繼承position屬性的值 |
| static | 默認(rèn)值, 沒(méi)有定位, 元素出現(xiàn)在正常的流中(此時(shí) top, right, bottom, left 和 z-index 屬性無(wú)效) |
| relative | 生成相對(duì)定位的元素, 相對(duì)于元素本身正常位置進(jìn)行定位,因此left: 20px; 會(huì)向元素的left位置添加 20px |
| absolute | 生成絕對(duì)定位的元素,相對(duì)于static定位以外的第一個(gè)祖先元素(offset parent)進(jìn)行定位,元素位置通過(guò)left,top,right以及bottom屬性進(jìn)行規(guī)定 |
| fixed | 生成絕對(duì)定位的元素, 相對(duì)于瀏覽器窗口進(jìn)行定位。元素的位置通過(guò)left,top,right以及bottom屬性進(jìn)行規(guī)定 |
| sticky | CSS 3 新屬性,兼容性差,一般用JS實(shí)現(xiàn)。表現(xiàn)類似position: relative和 position: absolute 的合體。在目標(biāo)區(qū)域在屏幕中可見(jiàn)時(shí),它的行為就像position: relative; 而當(dāng)頁(yè)面滾動(dòng)超出目標(biāo)區(qū)域時(shí),它的表現(xiàn)就像position: fixed,它會(huì)固定在目標(biāo)位置 |
TIPS :只有relative,absolute,fixed可以設(shè)置left,top,right,bottom 的值
position:relative 和 負(fù)margin 區(qū)別
position:relative和負(fù)margin都可以使元素位置發(fā)生偏移,二者有什么區(qū)別呢?
- 使用position: relative對(duì)元素進(jìn)行偏移時(shí),由于元素在文檔流中占據(jù)原來(lái)空間,相對(duì)自己原本的位置偏移,不影響其它普通流中元素的位置
- 使用負(fù)margin 的話, 除了讓元素自身發(fā)生偏移還影響其它普通流中的元素
BFC
BFC是什么
BFC的全稱是block formatting context (塊級(jí)格式化上下文),是Web頁(yè)面的可視化CSS渲染出的一部分。它是塊級(jí)盒布局出現(xiàn)的區(qū)域,也是浮動(dòng)層元素進(jìn)行交互的區(qū)域。
BFC是一個(gè)名詞,是一個(gè)獨(dú)立的布局環(huán)境,我們可以理解為一個(gè)箱子(實(shí)際上是看不見(jiàn)摸不著的),箱子里面物品的擺放是不受外界的影響的。
如何生成 BFC
W3C標(biāo)準(zhǔn)中這樣描述:
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with ‘overflow’ other than ‘visible’ (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
非塊級(jí)盒子的浮動(dòng)元素、絕對(duì)定位元素及塊級(jí)容器(比如inline-blocks,table-cells和table-captions),以及overflow屬性是visible之外任意值的塊級(jí)盒子,都會(huì)創(chuàng)建了一個(gè)BFC。即當(dāng)元素CSS屬性設(shè)置了下列之一時(shí),即可創(chuàng)建一個(gè)BFC:
float:left|right
position:absolute|fixed
display: table-cell|table-caption|inline-block
overflow: hidden|scroll|auto
注意:浮動(dòng)不會(huì)影響其它塊格式化上下文中元素的布局,并且清除浮動(dòng)只能清除同一塊格式化上下文中在它前面的元素的浮動(dòng)。
BFC 作用
- BFC會(huì)阻止垂直外邊距(margin-top, margin-bottom)折疊
創(chuàng)建了塊級(jí)格式化上下文的元素,不和它的子元素發(fā)生 margin 折疊(垂直方向的)

- BFC不會(huì)重疊浮動(dòng)元素
由于浮動(dòng)元素的層級(jí)比不浮動(dòng)的元素層級(jí)高, 所以浮動(dòng)元素會(huì)重疊后面的非浮動(dòng)元素,我們只要讓后面的元素形成BFC,就可以解決遮擋問(wèn)題了

利用BFC使文字不再圍繞浮動(dòng)元素, 形成兩欄布局

- BFC清除浮動(dòng)(實(shí)質(zhì)是讓父元素形成BFC包含浮動(dòng))

塊格式化上下文對(duì)于定位與清除浮動(dòng)很重要。定位和清除浮動(dòng)的樣式規(guī)則只適用于處于同一塊格式化上下文內(nèi)的元素。浮動(dòng)不會(huì)影響其它塊格式化上下文中元素的布局,并且清除浮動(dòng)只能清除同一塊格式化上下文中在它前面的元素的浮動(dòng)。
外邊距合并
塊的頂部外邊距和底部外邊距有時(shí)被組合(折疊)為單個(gè)外邊距,這種行為稱為外邊距塌陷(margin collapsing),有的地方翻譯為外邊距合并。
外邊距合并的場(chǎng)景
-
相鄰的兄弟姐妹元素外邊距合并
毗鄰的兩個(gè)兄弟元素之間的外邊距會(huì)塌陷(除非后者兄弟姐妹需要清除過(guò)去的浮動(dòng))
例如下面box1和box2合并后的外邊距是兩個(gè)外邊距中的較大值 40px
相鄰元素外邊距合并.png -
塊級(jí)父元素與其第一個(gè)/最后一個(gè)子元素外邊距合并
如果塊級(jí)父元素中,不存在上邊框、上內(nèi)邊距、內(nèi)聯(lián)元素、清除浮動(dòng)這四條屬性(也可以說(shuō),當(dāng)上邊框?qū)挾燃吧蟽?nèi)邊距距離為0時(shí)),那么這個(gè)塊級(jí)元素和其第一個(gè)子元素的上邊距就可以說(shuō)”挨到了一起“。
此時(shí)這個(gè)塊級(jí)父元素和其第一個(gè)子元素就會(huì)發(fā)生上外邊距合并現(xiàn)象,換句話說(shuō),此時(shí)這個(gè)父元素對(duì)外展現(xiàn)出來(lái)的外邊距將直接變成這個(gè)父元素和其第一個(gè)子元素的margin-top的較大者。
類似的,塊級(jí)父元素的 margin-bottom與它的最后一個(gè)子元素的margin-bottom之間會(huì)發(fā)生下外邊距合并現(xiàn)象。
下例中父元素ct 與它第一個(gè)子元素box1的外邊距合并, 對(duì)外展現(xiàn)外邊距30px
父子外邊距合并.png 空塊元素外邊距合并
如果存在一個(gè)空的塊級(jí)元素,其 border、padding、inline content、height、min-height 都不存在。那么此時(shí)它的上下邊距中間將沒(méi)有任何阻隔,此時(shí)它的上下外邊距將會(huì)合并
我們先來(lái)看空元素box1沒(méi)有外邊距的時(shí)候,box2是緊挨body的

然后我們來(lái)給空元素box1添加外邊距,這里我們?yōu)榱烁庇^的看空元素的外邊距到底會(huì)發(fā)生什么變化, 給box2也設(shè)置一個(gè)左外邊距

可以看到空元素box1 的上下外邊距也發(fā)生了合并
關(guān)于外邊距合并,可以看下MDN 上的介紹https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing
合并后外邊距大小
- 兩個(gè)合并的margin都是正值的時(shí)候,其大小是其中的最大外邊距;
- 在負(fù)外邊距的情況下,合并后的外邊距為最大正外邊距與最小負(fù)外邊距(即負(fù)邊距中絕對(duì)值最大的一個(gè))之和
- 當(dāng) margin 都是負(fù)值的時(shí)候,合并后的外邊距是比較小的外邊距
- 所有毗鄰的margin要一起參與運(yùn)算,不能分步進(jìn)行
阻止相鄰元素外邊距合并
不讓相鄰元素外邊距合并的方法
- 被非空內(nèi)容、padding、border 或 clear 分隔開(kāi)
- 不在一個(gè)普通流中或一個(gè)BFC中
- margin在垂直方向上不毗鄰
實(shí)例
-
對(duì)于父子外邊距合并
父子外邊距合并了.png
(1)可以通過(guò)給父元素加border/ padding來(lái)阻止外邊距合并

(2)創(chuàng)建了塊級(jí)格式化上下文的元素,不和它的子元素發(fā)生 margin 折疊

- 對(duì)于相鄰塊元素
(1)浮動(dòng)元素、inline-block 元素、絕對(duì)定位元素的 margin 不會(huì)和垂直方向上其他元素的 margin 折疊。所以我們只要根據(jù)需要給兩個(gè)塊元素添加相關(guān)屬性就好了,太多了,就不截圖了......
(2)利用BFC防止margin折疊(與阻止父子外邊距折疊用法有區(qū)別),見(jiàn)下圖:

例外的情況
- 根元素的外邊距不會(huì)參與折疊
- 不設(shè)置任何屬性的空span和空div不影響任何布局,可以無(wú)視之。


