CSS進(jìn)階07-浮動(dòng)Floats

(注1:如果有問題歡迎留言探討,一起學(xué)習(xí)!轉(zhuǎn)載請(qǐng)注明出處,喜歡可以點(diǎn)個(gè)贊哦!)
(注2:更多內(nèi)容請(qǐng)查看我的目錄。)

1. 簡(jiǎn)介

在當(dāng)前行中一個(gè)盒被移動(dòng)到左側(cè)或右側(cè)稱為浮動(dòng)。浮動(dòng)最有趣的特點(diǎn)是內(nèi)容可以在其側(cè)面流動(dòng)(或者被 clear 屬性禁止這樣做)。內(nèi)容沿著左浮動(dòng)框的右側(cè)向下流動(dòng),并沿右浮動(dòng)框的左側(cè)向下流動(dòng)。下面我們來看一下 浮動(dòng)定位 和 內(nèi)容流。

2.浮動(dòng)對(duì)布局的影響

浮動(dòng)盒將向左或向右移動(dòng),直到其外邊緣接觸包含塊邊緣或另一個(gè)浮動(dòng)的外邊緣。如果存在行盒,浮動(dòng)盒的外部頂部outer top將與當(dāng)前行盒的頂部對(duì)齊。

如果水平方向沒有足夠的空間容納浮動(dòng),它將下移直至能夠放下它或者沒有其他浮動(dòng)存在。

由于浮動(dòng)不在標(biāo)準(zhǔn)流中,在浮動(dòng)之前或之后創(chuàng)建的非定位塊盒將垂直擺放,如同浮動(dòng)不存在一樣。然而,如果當(dāng)前行盒和隨浮動(dòng)后創(chuàng)建的行盒與浮動(dòng)相鄰,會(huì)按需縮短來為浮動(dòng)的margin box騰出空間。

當(dāng)一個(gè)垂直定位滿足以下全部四個(gè)條件時(shí),行盒將與浮動(dòng)相鄰:

  • 在行盒頂部或之下
  • 在行盒底部或之上
  • 在浮動(dòng)的top margin edge 之下,
  • 在浮動(dòng)bottom margin edge之上

注:這意味著總高度 Outer Height 為零或?yàn)樨?fù)的浮動(dòng)不會(huì)縮短行盒。

如果行盒被縮短到不能容納任何內(nèi)容,那么行盒將下移(其寬度會(huì)重新計(jì)算)直到可以容納內(nèi)容或不再有浮動(dòng)。當(dāng)前行中,任何在浮動(dòng)盒之前的內(nèi)容將重排到同一行中的浮動(dòng)的另一側(cè)。換句話說,如果行內(nèi)級(jí)盒先于左浮動(dòng)被放在行盒中,而行盒的剩余空間可以容納左浮動(dòng),那么左浮動(dòng)會(huì)被置于該行內(nèi),且與行盒頂部對(duì)齊,而已經(jīng)放入該行盒的行內(nèi)級(jí)盒會(huì)被相應(yīng)地移動(dòng)到浮動(dòng)的右側(cè)(右側(cè)即是左浮動(dòng)的另一側(cè)),反過來對(duì) rtl 和右浮動(dòng)也是這樣。

表的border box、塊級(jí)可替換元素或者在標(biāo)準(zhǔn)流中創(chuàng)建了新的BFC的元素(比如 overflow 值非 visibile 的元素),它們不能與其同屬一個(gè)BFC中的浮動(dòng)元素的margin box重疊。如果有必要,應(yīng)當(dāng)通過把它們置于已出現(xiàn)的浮動(dòng)的下面達(dá)到清除浮動(dòng)的效果,但如果空間足夠,可能將其緊鄰浮動(dòng)放置,但這可能使得該元素的border變得比section 10.3.3定義的要窄。CSS2并沒有定義用戶代理何時(shí)會(huì)把元素置于浮動(dòng)旁,也沒有定義元素會(huì)變得多窄。

看一個(gè)例子,在下面的文檔片段中,包含塊太窄不足以容納緊鄰浮動(dòng)的內(nèi)容,所以這塊內(nèi)容需要移動(dòng)到浮動(dòng)下面,并根據(jù)其 text-align 屬性在行盒中對(duì)齊。

p {
   width: 10em;
   border: solid aqua;
}
span {
   float: left;
   width: 5em;
   height: 5em;
   border: solid blue;
}
...
<p>
   <span> </span>
   Supercalifragilisticexpialidocious
</p>

該片段可能如下圖所示:


若干浮動(dòng)會(huì)相鄰,而這個(gè)模型也適用于同一行中的相鄰的浮動(dòng)元素。

看下例,下面的規(guī)則會(huì)使所有的 class="icon" 的 img 盒浮動(dòng)到左側(cè)(并設(shè)置左外邊距為 0 )。

img.icon { 
   float: left;
   margin-left: 0;
}

考慮如下HTML代碼和樣式表:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Float example</title>
<style type="text/css">
   img { float: left }
   body, p, img { margin: 2em }
</style>
</head>
<body>
   <p><img src=img.png alt="This image will illustrate floats">
   Some sample text that has no other...
</body>
</html>

img 盒向左浮動(dòng)。其后的內(nèi)容被格式化到浮動(dòng)的右側(cè),從浮動(dòng)所在的同一行開始布局。由于浮動(dòng)的存在,浮動(dòng)右側(cè)的行盒縮短,但在浮動(dòng)之后就恢復(fù)了它們“正常”寬度(即 p 元素創(chuàng)建的包含塊的寬度)。該文檔可能被格式化如下:



如果文檔如下,格式化的結(jié)果是一樣的:

<body>
   <p>Some sample text 
   <img src=img.png alt="This image will illustrate floats">
   that has no other...
</body>

這是因?yàn)楦?dòng)左側(cè)的內(nèi)容為浮動(dòng)所替代,并被向下重排到了浮動(dòng)的右側(cè)。

正如8.3.1節(jié)
所述,浮動(dòng)元素的margins絕對(duì)不會(huì)與相鄰盒的margins折疊。因此,在之前的例子中, p 盒和 img 浮動(dòng)盒的垂直外邊距不會(huì)折疊。

浮動(dòng)的內(nèi)容會(huì)像浮動(dòng)創(chuàng)建了新的堆疊上下文 Stacking Context 一樣堆疊起來,但定位元素、創(chuàng)建了新的堆疊上下文并參與了浮動(dòng)的父級(jí)堆疊上下文的元素除外。浮動(dòng)可以同常規(guī)流中的其他盒重疊(例如,當(dāng)浮動(dòng)旁邊的常規(guī)流盒有負(fù)margin的時(shí)候)。當(dāng)發(fā)生重疊時(shí),浮動(dòng)會(huì)被渲染在非定位文檔流內(nèi)塊 Non-positioned In-flow Blocks 之上,文檔流內(nèi)行內(nèi)盒之下。

這有個(gè)例子,演示了浮動(dòng)與常規(guī)流中元素的邊框重疊的情況。



浮動(dòng)圖片擋住了與其重疊的塊盒的邊框。

下面的例子演示了使用 clear 屬性阻止內(nèi)容緊鄰浮動(dòng)。
假設(shè)規(guī)則如下:

p { clear: left }

格式化結(jié)果可能如下所示:



兩個(gè)段落都設(shè)置了 clear: left ,因此使得第二個(gè)段落“被往下推”到浮動(dòng)之下的位置,這是“空隙clearance”被添加到其top margin 之上的結(jié)果。

3. 浮動(dòng)定位:float屬性

float

這個(gè)屬性指定一個(gè)盒子是應(yīng)該向左浮動(dòng),向右浮動(dòng)還是不浮動(dòng)。它可以被任何元素設(shè)置,但僅適用于生成非絕對(duì)定位盒的元素。該屬性值具有如下含義:

  • left
    該元素生成一個(gè)浮動(dòng)到左側(cè)的塊盒。內(nèi)容在盒的右側(cè)從頂部向下流動(dòng)(受clear屬性限制)
  • right
    該元素生成一個(gè)浮動(dòng)到右側(cè)的塊盒。內(nèi)容在盒的左側(cè)從頂部向下流動(dòng)(受clear屬性限制)
  • none
    該盒不浮動(dòng)

用戶代理會(huì)視根元素上的 float 為 none 。
以下是控制浮動(dòng)行為的準(zhǔn)則:

  1. 左浮動(dòng)盒的左外邊緣不可在其包含塊的左邊緣之左。右浮動(dòng)元素亦是。

  2. 如果當(dāng)前盒是左浮動(dòng),而此前源文檔中已有元素生成了左浮動(dòng)盒,那么對(duì)每個(gè)此前生成的盒而言,要么當(dāng)前盒的左外邊緣在此前生成盒的右外邊緣之右,要么當(dāng)前盒的頂部必須低于此前生成盒的底部。右浮動(dòng)元素亦是。

  3. 左浮動(dòng)盒的右外邊緣不可在其旁邊的右浮動(dòng)盒的左外邊緣之右。右浮動(dòng)元素亦是。

  4. 浮動(dòng)盒的上外邊緣不可高于其包含塊的頂部。當(dāng)浮動(dòng)出現(xiàn)兩個(gè)折疊外邊距之間時(shí),浮動(dòng)會(huì)如同它有一個(gè)參與標(biāo)準(zhǔn)流的空匿名父塊一樣來定位。該父塊的位置由關(guān)于外邊距折疊那章的規(guī)則定義。

  5. 浮動(dòng)盒的上外邊緣不可高于源文檔中此前元素生成的塊盒或浮動(dòng)盒的上外邊緣。

  6. 元素的浮動(dòng)盒的上外邊緣不可高于源文檔中此前元素生成的盒所在的行盒的頂部。

  7. 一個(gè)左浮動(dòng)盒如果有其他左浮動(dòng)盒在其左側(cè),其右外邊緣不可在其包含塊的右邊緣之右。(寬松點(diǎn)的要求是:左浮動(dòng)不可超出其包含塊的右邊緣,除非該盒已經(jīng)盡可能靠左了。)右浮動(dòng)元素亦是。

  8. 浮動(dòng)盒必須盡可能地往高擺放。

  9. 左浮動(dòng)盒的擺放必須盡可能地靠左,右浮動(dòng)盒必須盡可能靠右。更高的位置優(yōu)先于更靠近左/右的位置。



    但是在CSS2.2中,如果,在BFC中,有一個(gè)文檔流內(nèi)負(fù)垂直高度的外邊距,使得浮動(dòng)的位置高于它原本應(yīng)當(dāng)在的位置,所有這種負(fù)外邊距被設(shè)為零,浮動(dòng)的位置則未定義。

這些規(guī)則中提到的其他元素僅指:和浮動(dòng)同屬一個(gè)BFC的其他元素。

這個(gè)HTML片段結(jié)果為 b 向右浮動(dòng)

<p>a<span style="float: right">b</span></p>

如果 p 元素足夠?qū)挘?a 和 b 則會(huì)各占一邊,如下所示:


4. 控制浮動(dòng)旁的流: clear 屬性

clear

該屬性指定元素的哪些側(cè)邊不允許同此前的浮動(dòng)盒相鄰。 clear 屬性不考慮其元素本身內(nèi)的浮動(dòng)或者處于其他BFC的浮動(dòng)。

各值被應(yīng)用于非浮動(dòng)塊級(jí)盒時(shí),具有如下意義:

left:要求盒的top border edge低于源文檔內(nèi)此前元素生成的左浮動(dòng)盒的bottom outer edge。

right:要求盒的top border edge低于源文檔內(nèi)此前元素生成的右浮動(dòng)盒的bottom outer edge。

both:要求盒的top border edge低于源文檔內(nèi)此前元素生成的左、右浮動(dòng)盒的bottom outer edge。

none:對(duì)盒相對(duì)于浮動(dòng)的定位沒有約束。

clear 取非 none 值可能產(chǎn)生空隙 Clearance 。空隙阻止外邊距折疊并充當(dāng)元素上外邊距margin-top之上的空間。空隙被用于推動(dòng)元素在垂直方向上越過浮動(dòng)。

計(jì)算設(shè)置了 clear 值的元素的空隙,首先要計(jì)算元素top border edge的假定位置,該位置即元素 clear 屬性值為 none 時(shí)實(shí)際top border edge應(yīng)該在的位置。

如果元素上邊框邊緣的假定位置沒有越過有關(guān)浮動(dòng),那么空隙就會(huì)產(chǎn)生,并且外邊距折疊要根據(jù)8.3.1章規(guī)則計(jì)算。

空隙的高度被設(shè)為下述中的較大值:

  1. 塊的邊框邊緣border edge與要被清除的最下方的浮動(dòng)的下外邊緣bottom outer edge不相交的必要高度。

  2. 將塊的上邊框邊緣top border edge放在其假定位置的必要高度。

二選一的話,空隙高度即第一種。

注:兩種方式在目前的網(wǎng)頁內(nèi)容的兼容性上有待評(píng)估。未來的CSS規(guī)范將規(guī)定為其中一個(gè)或另一個(gè)。
注:空隙可以為負(fù)或?yàn)榱恪?/p>

來看兩個(gè)例子:

eg1:假設(shè)(為簡(jiǎn)單起見)有三個(gè)盒,順序如下: B1 塊的下外邊距bottom margin為 M1 ( B1 沒有子元素也沒有padding和border);浮動(dòng)塊 F 的高度為 H , B2 塊top margin為 M2 (沒有padding或border,沒有子元素)。 B2 的 clear 設(shè)為 both 。同時(shí)假設(shè) B2 不為空。

不考慮 B2 的 clear 屬性,情況如下圖所示。 B1 和 B2 的外邊距margins折疊。 B1 的bottom border edge在 y = 0 的位置, F 的top在 y = M1 的位置, B2 的top border edge在 y = max(M1,M2) 的位置, F 的bottom在 y = M1+H 的位置。


同時(shí)假設(shè) B2 不在 F 之下,也就是說,正如規(guī)范說明的情況,我們需要添加空隙。

max(M1,M2) < M1 + H

我們需要計(jì)算空隙 C兩次,即C1 和 C2 ,并取二者較大值: C = max(C1,C2) 。第一種方法是把 B2 的頂部top和 F 的底部bottom齊平,即,放在 y= M1+H 。也意味著外邊距之間的空隙使得外邊距不再折疊:

bottom of F = top border edge of B2 ?
M1 + H = M1 + C1 + M2   ?
C1 = M1 + H - M1 - M2
= H - M2

第二次計(jì)算是保持 B2 頂部位置,即 y=max(M1,M2) 處,這意味著:

max(M1,M2) = M1 + C2 + M2   ?
C2 = max(M1,M2) - M1 - M2

假設(shè) max(M1,M2) < M1 + H,這意味著:

C2 = max(M1,M2) - M1 - M2   < M1 + H - M1 - M2 = H - M2 ?
C2  < H - M2

又因?yàn)?C1 = H - M2,得

C2 < C1

因此

C = max(C1,C2) = C1

eg2: 本例中空隙的高度為負(fù)值-1em。(假設(shè)所有元素都沒有邊框或borders者內(nèi)邊距padding)

<p style="margin-bottom: 4em">
   First paragraph.
</p>
<p style="float: left; height: 2em; margin: 0">
   Floating paragraph.
</p>
<p style="clear: left; margin-top: 3em">
   Last paragraph.
</p>

說明:要是沒有 clear ,首段和末段兩個(gè)段落的邊距將會(huì)折疊并且末段的上邊框邊緣將同浮動(dòng)段落的頂部齊平。如下:


但 clear 使得上邊框邊緣低于浮動(dòng),即下降2em。這意味著一定會(huì)產(chǎn)生空隙。



由此,外邊距不再折疊,空隙的高度 clearance 滿足

clearance + margin-top = 2em

也就是說,

clearance = 2em - margin-top = 2em - 3em = -1em

當(dāng) clear 設(shè)在浮動(dòng)元素上時(shí),將造成第3節(jié)所述浮動(dòng)定位規(guī)則的修正。補(bǔ)充第10條額外規(guī)定如下:

(當(dāng) clear 設(shè)在浮動(dòng)元素上時(shí),)浮動(dòng)的上外邊緣top outer edge必須低于所有此前左浮動(dòng)盒的下外邊緣bottom outer edge( clear: left 情形下),或者低于所有此前的右浮動(dòng)盒的下外邊緣( clear: right 情形下),或者低于此前左右浮動(dòng)盒的下外邊緣( clear: both 情形下)。

注意:CSS1中該屬性適用于所有元素,因此所有元素都能實(shí)現(xiàn)效果。在CSS2和CSS2.2中, clear 屬性僅支持塊級(jí)元素。因此開發(fā)者們應(yīng)當(dāng)只將此屬性應(yīng)用于塊級(jí)元素。如果要實(shí)現(xiàn)行內(nèi)元素清除浮動(dòng)效果,不應(yīng)當(dāng)如上所講的去設(shè)置空隙,而應(yīng)當(dāng)強(qiáng)制斷行并有效插入一個(gè)或多個(gè)空行盒(或者如section 9.5所講移動(dòng)新行盒)來使要清除浮動(dòng)的行內(nèi)元素的行盒低于相應(yīng)的浮動(dòng)盒。

參考

https://www.w3.org/TR/CSS22/visuren.html#visual-model-intro
https://www.w3.org/TR/CSS2/visuren.html
CSS規(guī)范 > 9 視覺格式化模型 Visual Formatting Model

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,923評(píng)論 6 535
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,740評(píng)論 3 420
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,856評(píng)論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,175評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,931評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,321評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,383評(píng)論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,533評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,082評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,891評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,067評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,618評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,319評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,732評(píng)論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,987評(píng)論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,794評(píng)論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,076評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,777評(píng)論 1 92
  • 1.CSS基本概念 1.1 CSS的定義 CSS(Cascading Style Sheets)層疊樣式表,主要用...
    寥寥十一閱讀 1,860評(píng)論 0 6
  • CSS 是什么 css(Cascading Style Sheets),層疊樣式表,選擇器{屬性:值;屬性:值}h...
    崔敏嫣閱讀 1,505評(píng)論 0 5
  • 浮動(dòng)元素有什么特征?對(duì)父容器、其他浮動(dòng)元素、普通元素、文字分別有什么影響? 特征: 脫離正常文檔流,沿其容器的左側(cè)...
    _Dot912閱讀 729評(píng)論 0 3
  • 1. IFC與line box IFC的英文全稱是:Inline Formatting Contexts,直譯為“...
    love丁酥酥閱讀 1,480評(píng)論 0 0