簡單說一下 [清除 & 閉合] 浮動

本文的原由是團隊如今處於缺人的階段,最近開始幫忙進行電話面試的操做。面了很多了,有很多收穫,其中最大的仍是對本身的警戒做用。雖然是本身在面試別人,但也發現,不少在交流過程當中涉及到的內容,本身雖然都知道或者有了解,可是要系統或者清晰的描述出來實際上是不容易的,因此開始整理一些看似都懂的一些「亂七八糟」的知識。css

【本文主要是根據參考資料整理以及一些本身的理解,參考資料已在文末列出。】html

浮動是一個CSS佈局中的經典屬性,用過浮動的小夥伴確定會遇到須要清除浮動或者說閉合浮動的狀況。我對清除仍是閉合的理解是,看你的實現方法來講。面試

簡單來講,使用clear屬性來實現能夠認爲是清除浮動(clearing float),使元素生成BFC或者hasLayout屬性爲true的方法能夠稱之爲閉合浮動(enclosing float)。瀏覽器

CSS中的定位機制能夠分爲:ide

  • 普通流(俗稱文檔流,可是標準裏面爲normal flow,因此稱之爲普通流比較合理)。
  • 浮動:引用一絲姐姐的文章中的話以下,須要注意的點是浮動框會一直浮動到包含框或者另外一個浮動框爲止,而且浮動的元素是脫離普通流的,脫離了以後只會影響普通流中的內聯元素的佈局,對於塊級元素沒有影響,就像這個浮動元素不存在同樣。同時,有可能會出現「高度塌陷」的狀況(這也是清除&閉合浮動需求的主要場景)。

浮動的框能夠左右移動,直至它的外邊緣遇到包含框或者另外一個浮動框的邊緣。浮動框不屬於文檔中的普通流,當一個元素浮動以後,不會影響到塊級框的佈局而只會影響內聯框(一般是文本)的排列,文檔中的普通流就會表現得和浮動框不存在同樣,當浮動框高度超出包含框的時候,也就會出現包含框不會自動伸高來閉合浮動元素(「高度塌陷」現象)。佈局

  • 絕對定位:不是本文的重點,就很少說了。簡單來講,絕對定位的元素是脫離普通流的,相對於最近的display屬性爲非static的父級元素定位。

閉合浮動

閉合浮動的本質就是讓元素產生BFC或者hasLayout屬性爲true。post

BFC的建立方法(參考自Block formatting context MDN),加粗的爲常見或者須要注意的方法:學習

  • the root element or something that contains it
  • floats (elements where float is not none)
  • absolutely positioned elements (elements where position is absolute or fixed)
  • inline-blocks (elements with display: inline-block)
  • table cells (elements with display: table-cell, which is the default for HTML table cells)
  • table captions (elements with display: table-caption, which is the default for HTML table captions)
  • anonymous table cells implicitly created by the elements with display: table, table-row, table-row-group, table-header-group, table-footer-group (which is the default for HTML tables, table rows, table bodies, table headers and table footers, respectively), or inline-table
  • block elements where overflow has a value other than visible
  • display: flow-root
  • elements with contain: layout, content, or strict
  • flex items (direct children of the element with display: flex or inline-flex)
  • grid items (direct children of the element with display: grid or inline-grid)
  • multicol containers (elements where column-count or column-width is not auto, including elements with column-count: 1)
  • column-span: all should always create a new formatting context, even when the column-span: all element isn't contained by a multicol container (Spec change, Chrome bug).

對於hasLayout屬性,一絲的文章中:flex

IE6-7的顯示引擎使用的是一個稱爲佈局(layout)的內部概念,因爲這個顯示引擎自身存在不少的缺陷,直接致使了IE6-7的不少顯示bug。當咱們說一個元素「獲得 layout」,或者說一個元素「擁有 layout」 的時候,咱們的意思是指它的微軟專有屬性 hasLayout http://msdn.microsoft.com/worksh ... rties/haslayout.asp 爲此被設爲了 true 。IE6-7使用佈局的概念來控制元素的尺寸和定位,那些擁有佈局(have layout)的元素負責自己及其子元素的尺寸設置和定位。若是一個元素的 hasLayout 爲false,那麼它的尺寸和位置由最近擁有佈局的祖先元素控制。ui

簡單來講,就是舊版本IE特有的一個控制佈局的概念,對於咱們來講要考慮的是在處理IE的兼容性的時候須要留意這個屬性,從表現上來講,能夠將hasLayout等同於BFC來考慮。

觸發hasLayout的條件:

  • position: absolute
  • float: left|right
  • display: inline-block
  • width: 除 「auto」 外的任意值
  • height: 除 「auto」 外的任意值 (例如不少人閉合浮動會用到 height: 1% )
  • zoom: 除 「normal」 外的任意值 (MSDN) http://msdn.microsoft.com/worksh ... properties/zoom.asp
  • writing-mode: tb-rl (MSDN) http://msdn.microsoft.com/worksh ... ies/writingmode.asp

在 IE7 中,overflow 也變成了一個 layout 觸發器:

  • overflow: hidden|scroll|auto ( 這個屬性在IE以前版本中沒有觸發 layout 的功能。 )
  • overflow-x|-y: hidden|scroll|auto (CSS3 盒模型中的屬性,還沒有獲得瀏覽器的普遍支持。他們在以前IE版本中一樣沒有觸發 layout 的功能)

這麼多的觸發條件,其實須要記住的就是:最無害和被你們用來處理舊版本IE閉合浮動兼容性的是zoom

BFC

對於爲何觸發了BFC能夠實現閉合浮動的效果,從BFC的定義來看:

A block formatting context contains everything inside of the element creating it that is not also inside a descendant element that creates a new block formatting context.

簡單來講,BFC的一個最重要的效果是,讓處於BFC內部的元素與外部的元素相互隔離,使內外元素的定位不會相互影響,這是利用BFC清除浮動所利用的特性。

此外BFC的特性主要的能夠記住如下幾點:

  • 內部的盒會在垂直方向一個接一個排列,也就是BFC內部是一個普通流;
  • 處於同一個BFC中的元素相互影響,可能會發生margin collapse;【防止上下margin collapse問題
  • 每一個元素的margin box的左邊,與容器塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此; BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素,反之亦然;
  • 計算BFC的高度時,考慮BFC所包含的全部元素,連浮動元素也參與計算;【解決「高度塌陷問題」
  • 浮動盒區域不疊加到BFC上;【文本清除浮動,防止文字環繞效果

清除浮動

清除浮動用的就是clear屬性配合both屬性值了。能夠用額外的元素放到包含塊的尾部,或者使用僞元素設置clear both來實現。我的推薦比較好的方法是使用僞類,而後配合IE的hasLayout兼容的方法,在一絲姐姐的文章中的那個最佳解:

.clearfix:after {
    content:".";
    display:block;
    height:0;
    visibility:hidden;
    clear:both;
}
.clearfix {
    *zoom:1;
}
複製代碼

另外在一絲的文章的最後提到了Nicolas Gallagher的文章中的方法:

.clearfix:before,.clearfix:after {
    content:"";
    display:table;
}
.clearfix:after {
    clear:both;
}/* For IE 6/7 (trigger hasLayout) */
.clearfix {
    zoom:1;
}
複製代碼

這裏的重點是這個before的僞元素的做用,效果是處理內部元素的margin和上面的外部的元素的margin發生疊加的。個人理解是清除浮動的做用只是在元素的最後經過clear: both的方法實現了清除浮動從而消除了高度塌陷這些問題。可是本質上並無造成一個BFC,也就是不會有BFC的其餘的一些做用,好比防止上下margin collapse的問題。這裏經過設置一個before的的display的table的元素(造成BFC)來解決頂部margin collapse的問題。

參考資料:

相關文章
相關標籤/搜索