css之高度塌陷及其解決方法


淺談 清除浮動 的多種方式(clearfix)

1.什么是浮動 ? 是否脫離文檔流?

1、普通流定位 static(默認方式) 

普通流定位,又稱為文檔流定位,是頁面元素的默認定位方式 
頁面中的塊級元素:按照從上到下的方式逐個排列 
頁面中的行內元素:按照從左到右的方式逐個排列 
但是如何讓多個塊級元素在一行內顯示? 
這里就引出了浮動定位 

2、浮動定位 float 

float屬性 取值為 left/right 

脫離文檔流

3、相對定位 relative 

元素會相對於它原來的位置偏移某個距離,改變元素位置后,元素原本的空間依然會被保留 
語法 
屬性:position 
取值:relative 
配合着 偏移屬性(top/right/bottom/left)實現位置的改變

4、絕對定位 absolute 

如果元素被設置為絕對定位的話,將具備以下幾個特征 
1、脫離文檔流-不占據頁面空間 
2、通過偏移屬性固定元素位置 
3、相對於 最近的已定位的祖先元素實現位置固定 
4、如果沒有已定位祖先元素,那么就相對於最初的包含塊(body,html)去實現位置的固定 
語法 
屬性:position 
取值:absolute 
配合着 偏移屬性(top/right/bottom/left)實現位置的固定

5、固定定位 fixed 

將元素固定在頁面的某個位置處,不會隨着滾動條而發生位置移動 
語法 
屬性:position 
取值:fixed 
配合着 偏移屬性(top/right/bottom/left)實現位置的固定

2.浮動的效果

    • 浮動 之后會怎么樣? 
      1、浮動定位元素會被排除在文檔流之外-脫離文檔流(不占據頁面空間),其余的元素要上前補位 
      2、浮動元素會停靠在父元素的左邊或右邊,或停靠在其他已浮動元素的邊緣上(元素只能在當前所在行浮動) 
      3、浮動元素依然位於父元素之內 
      4、浮動元素處理的問題-解決多個塊級元素在一行內顯示的問題 
      注意 
      1、一行內,顯示不下所有的已浮動元素時,最后一個將換行 
      2、元素一旦浮動起來之后,那么寬度將變成自適應(寬度由內容決定) 
      3、元素一旦浮動起來之后,那么就將變成塊級元素,尤其對行內元素,影響最大 
      塊級元素:允許修改尺寸 
      行內元素:不允許修改尺寸 
      4、文本,行內元素,行內塊元素時采用環繞的方式來排列的,是不會被浮動元素壓在底下的,會巧妙的避開浮動元素
    • 浮動 之后會有什么樣的影響? 
      由於浮動元素會脫離文檔流,所以導致不占據頁面空間,所以會對父元素高度帶來一定影響。如果一個元素中包含的元素全部是浮動元素,那么該元素高度將變成0(高度塌陷)

3.如何清除浮動

方案1

直接設置父元素的高度 
優勢:極其簡單 
弊端:必須要知道父元素高度是多少

方案2

在父元素中,追加空子元素,並設置其clear屬性為both 
clear是css中專用於清除浮動的屬性 
作用:清除當前元素前面的元素浮動所帶來的影響 
取值: 
1、none 
默認值,不做任何清除浮動的操作 
2、left 
清除前面元素左浮動帶來的影響 
3、right 
清除前面元素右浮動帶來的影響 
4、both 
清除前面元素所有浮動帶來的影響 
優勢:代碼量少 容易掌握 簡單易懂 
弊端:會添加許多無意義的空標簽,有違結構與表現的分離,不便於后期的維護

方案3

設置父元素浮動 
優勢:簡單,代碼量少,沒有結構和語義化問題 
弊端:對后續元素會有影響

方案4

為父元素設置overflow屬性 
取值:hidden 或 auto 
優勢:簡單,代碼量少 
弊端:如果有內容要溢出顯示(彈出菜單),也會被一同隱藏

方案5

父元素設置display:table 
優勢:不影響結構與表現的分離,語義化正確,代碼量少 
弊端:盒模型屬性已經改變,會造成其他問題

方案6

使用內容生成的方式清除浮動

1 .clearfix:after {
2    content:""; 
3    display: block; 
4    clear:both; 
5 }

:after 選擇器向選定的元素之后插入內容 
content:""; 生成內容為空 
display: block; 生成的元素以塊級元素顯示, 
clear:both; 清除前面元素浮動帶來的影響 
相對於空標簽閉合浮動的方法 
優勢:不破壞文檔結構,沒有副作用 
弊端:代碼量多

方案7

1 .cf:before,.cf:after {
2    content:"";
3    display:table;
4 }
5 .cf:after { clear:both; }

優勢:不破壞文檔結構,沒有副作用 
弊端: 代碼量多 
注意:display:table本身無法觸發BFC,但是它會產生匿名框(anonymous boxes),而匿名框中的display:table-cell可以觸發BFC,簡單說就是,觸發塊級格式化上下文的是匿名框,而不是display:table。所以通過display:table和display:table-cell創建的BFC效果是不一樣的(后面會說到BFC)。

CSS2.1 表格模型中的元素,可能不會全部包含在除HTML之外的文檔語言中。這時,那些“丟失”的元素會被模擬出來,從而使得表格模型能夠正常工作。
所有的表格元素將會自動在自身周圍生成所需的匿名table對象,使其符合table/inline-table、table-row、table- cell的三層嵌套關系。

疑問

為什么會margin邊距重疊? 
overflow:hidden, 語義應該是溢出:隱藏,按道理說,子元素浮動了,但依然是在父元素里的,而父元素高度塌陷,高度為0了,子元素應該算是溢出了,為什么沒有隱藏,反而撐開了父元素的高度? 
為什么display:table也能清除浮動,原理是什么?

解釋

要解釋這些疑問,我們就要提到Formatting context 
Formatting context是W3C CSS2.1規范中的一個概念。它是頁面中的一塊渲染區域,並且有一套渲染規則,它決定了其子元素將如何定位,以及和其他元素的關系和相互作用。 
最常見的Formatting context有Block fomatting context(簡稱BFC)和Inline formatting context(簡稱IFC)。 
CSS2.1 中只有BFC和IFC, CSS3中還增加了GFC和FFC 

這里主要說BFC

 BFC(Block formatting context)直譯為”塊級格式化上下文”。它是一個獨立的渲染區域,只有Block-level box參與, 它規定了內部的Block-level Box如何布局,並且與這個區域外部毫不相干。 block-level box,display屬性為block, list-item, table的元素,會生成block-level box。並且參與block fomatting context。 
inline-level box, display屬性為inline, inline-block, inline-table的元素,會生成inline-level box。並且參與inline formatting context。 
BFC布局規則: 
1、內部的Box會在垂直方向,按照從上到下的方式逐個排列。 
2、Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊 
3、每個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。 
4、BFC的區域不會與float box重疊。 
5、BFC就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。反之也如此。 
6、計算BFC的高度時,浮動元素的高度也參與計算

 觸發BFC的條件 

1、根元素 
2、float (left,right) 
3、overflow 除了visible 以外的值(hidden,auto,scroll ) 
4、display (table-cell,table-caption,inline-block) 
5、position(absolute,fixed)

 舉例詳解BFC

 1 <style>
 2    .top{
 3     width:100px;
 4     height:100px;
 5     background:red;
 6     margin:50px;
 7    }
 8    .bottom{
 9     width:100px;
10     height:100px;
11     background:blue;
12     margin:20px;
13    }
14 </style>
15 <body>
16     <div class="top">上</div>
17     <div class="bottom">下</div>
18 </body>

依據BFC布局規則第二條:

Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊 
注意:發生重疊后,外邊距的高度等於兩個發生重疊的外邊距的高度中的較大者
 1 <style>
 2    .top{
 3     width:100px;
 4     height:100px;
 5     background:red;
 6     float:left;
 7    }
 8    .bottom{
 9     width:200px;
10     height:200px;
11     background:blue;
12    }
13 </style>
14 <body>
15     <div class="top"></div>
16     <div class="bottom"></div>
17 </body>

依據BFC布局規則第三條:

每個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。 
我們可以看到,雖然有浮動的元素top,但是bottom的左邊依然與包含塊的左邊相接觸
 1 <style>
 2    .top{
 3     width:100px;
 4     height:100px;
 5     background:red;
 6     float:left;
 7    }
 8    .bottom{
 9     width:200px;
10     height:200px;
11     background:blue;
12     overflow:hidden;
13    }
14 </style>
15 <body>
16     <div class="top"></div>
17     <div class="bottom"></div>
18 </body>

依據BFC布局規則第四條:

BFC的區域不會與float box重疊。 
看代碼和效果圖,可以看出,這次的代碼比上面的代碼多了一行overflow:hidden;用這行代碼觸發新的BFC后,
由於這個新的BFC不會與浮動的top重疊,所以bottom的位置改變了
 1 <style>
 2    p{
 3     width:100px;
 4     height:100px;
 5     background:red;
 6     float:left;
 7    }
 8    div{
 9     width:200px;
10     border:1px solid blue;
11    }
12 </style>
13 <body>
14     <div>
15        <p></p>
16     </div>
17 </body>

當div增加 overflow:hidden; 時 效果如下

依據BFC布局規則第六條:

計算BFC的高度時,浮動元素的高度也參與計算。 
到此我們應該是解決了上面的所有疑問了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM