深刻理解css之float

前言

在css中,是存在流的概念的。在正常狀況下,頁面老是從左到右,從上到下佈局,這種被稱爲正常的流。可是有不少狀況,正常流是沒辦法實現的,所以咱們須要一些手段來破壞流,從而實現一些特殊的佈局,而本節的主角float就具有破壞流的特性。css

float設計的初衷

不少新手在佈局的時候,總喜歡用float來實現。例如一個三欄佈局,左右固定,中間自適應,有些人會經過float來一列一列把它們砌起來。這樣的佈局極其容易崩潰,只要高度或者寬度稍微有些變化,整個頁面都會錯亂。所以float設計的初衷並非用來佈局的,其本意僅僅是實現圖片文字環繞效果,即圖片左浮動,文字環繞圖片,以下圖所示:html

文字環繞

.float {
    width: 150px;
    float: left;
}
.content {
    width: 400px;
}
<div>
    <img src="./card.jpg" alt="" class="float">
    <p class="content">文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞</p>
</div>

float的特性

一個元素設置了float屬性,會表現出以下特性:瀏覽器

  • 包裹性
  • 塊狀格式化上下文
  • 破壞文檔流
  • 沒有margin合併

包裹性

包裹性包含了包裹和自適應兩個特性。佈局

包裹指的是一個浮動元素,若是子元素寬度足夠小,則浮動元素的寬度就是該子元素的寬度,以下所示:spa

包裹性

.float {
    float: left;
}
<p class="float">
    <span>這是浮動元素的子元素</span>
</p>

自適應指的是若是浮動元素的父元素有設置寬度,而且浮動元素的子元素寬度超出了父元素,則浮動元素的寬度最終表現爲父元素的寬度,以下所示:設計

自適應

.father {
    width: 100px;
}

.float {
    float: left;
}
<div class="father">
    <p class="float">
        <span>這是浮動元素的子元素</span>
    </p>
</div>

塊狀格式化上下文

設定了float的元素,其display的最終值會表現爲block或者table,具體轉換以下表:code

設定值 計算值
inline block
inline-block block
inline-table table
table-row block
table-row-group block
table-column block
table-column-group block
table-cell block
table-caption block
table-header-group block
table-footer-group block

所以,設置了float的元素,下面的寫法是多餘的:htm

.float {
        float: left:
        display: block;
    }

    .float {
        float: left;
        vertical-align: middle; /* 不起做用 */
    }

格式化上下文屬於BFC的內容,此處先不展開。圖片

破壞文檔流

這是float最本質的特性,所以float設計的初衷就是破壞文檔流。設置float的元素,會致使父元素高度塌陷,咱們來看個例子:文檔

破壞性

.float {
    float: left;
}
<div class="father">
    <img src="./card.jpg" alt="" class="float">
</div>
<p>
    文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞
</p>

能夠看到,父元素的高度爲0,但這不是bug,而是float自己就是這樣設計的,所以只有讓父元素高度塌陷了,後面的元素纔有機會浮上來。可是僅僅是這樣仍是不能夠造成圖片環繞效果的,否則文字浮上來就只會覆蓋在圖片上面。這裏面還隱藏着一個特性:

  • 行框盒子和浮動元素的不可重疊性

意思是說行框盒子和浮動元素不會發生重疊,所以,下面的文字浮上去以後纔不會覆蓋在圖片之上。即便咱們給文字設置margin負值也不會起做用。

沒有margin合併

設置了float的元素,因爲造成了BFC,所以也就沒有了margin合併。

float做用機制

咱們先來看個例子:

.float {
    float: right;
}
<div>
    <span>標題</span>
    <a class="float">連接</a>
</div>

在標準瀏覽器下,「標題」和「連接」會在同一行展現,而且「連接」會浮動在右邊。可是若是「標題」很是長,一行放不下呢,「連接」是浮動在第一行仍是第二行呢?答案是第二行,要想解釋這個,咱們得先理解兩個概念,一個是「浮動錨點」,一個是「浮動參考」:

  • 浮動錨點是float元素所在的「流」中的一個點,這個點自己並不浮動,表現得就像是一個沒有margin、padding和border的空的內聯元素。
  • 浮動參考指的是浮動元素對齊參考的實體。

float元素的「浮動參考」是行框盒子,也就是float元素在當前「行框盒子」內定位,所以,上面的例子「連接」會在第二行展現。可是也有一種狀況是,浮動元素先後並無內聯元素,所以也就不存在行框盒子,這時候就是「浮動錨點」在起做用。由於「浮動錨點」表現得像一個內聯元素,有內聯元素,天然就有行框盒子,只是這個盒子看不見也摸不着罷了。

float實現流體佈局

前面文字環繞的例子,只要稍微改造一下就能夠實現兩欄或多欄的自適應佈局,代碼以下:

.father {
    overflow: hidden;
    height: 200px;
}

.float {
    float: left;
    width: 100px;
}

.content {
    margin-left: 120px;
}
<div class="father">
    <img src="./card.jpg" alt="" class="float">
    <p class="content">文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞文字環繞</p>
</div>

總結

  • float設計的初衷不是佈局,而是文字環繞效果
  • float的特性:包裹性、塊狀格式化上下文、破壞性、沒有margin合併
  • float的機制:浮動錨點和浮動參考
  • float實現自適應佈局的思路
相關文章
相關標籤/搜索