(注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屬性
這個(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)則:
左浮動(dòng)盒的左外邊緣不可在其包含塊的左邊緣之左。右浮動(dòng)元素亦是。
如果當(dāng)前盒是左浮動(dòng),而此前源文檔中已有元素生成了左浮動(dòng)盒,那么對(duì)每個(gè)此前生成的盒而言,要么當(dāng)前盒的左外邊緣在此前生成盒的右外邊緣之右,要么當(dāng)前盒的頂部必須低于此前生成盒的底部。右浮動(dòng)元素亦是。
左浮動(dòng)盒的右外邊緣不可在其旁邊的右浮動(dòng)盒的左外邊緣之右。右浮動(dòng)元素亦是。
浮動(dòng)盒的上外邊緣不可高于其包含塊的頂部。當(dāng)浮動(dòng)出現(xiàn)兩個(gè)折疊外邊距之間時(shí),浮動(dòng)會(huì)如同它有一個(gè)參與標(biāo)準(zhǔn)流的空匿名父塊一樣來定位。該父塊的位置由關(guān)于外邊距折疊那章的規(guī)則定義。
浮動(dòng)盒的上外邊緣不可高于源文檔中此前元素生成的塊盒或浮動(dòng)盒的上外邊緣。
元素的浮動(dòng)盒的上外邊緣不可高于源文檔中此前元素生成的盒所在的行盒的頂部。
一個(gè)左浮動(dòng)盒如果有其他左浮動(dòng)盒在其左側(cè),其右外邊緣不可在其包含塊的右邊緣之右。(寬松點(diǎn)的要求是:左浮動(dòng)不可超出其包含塊的右邊緣,除非該盒已經(jīng)盡可能靠左了。)右浮動(dòng)元素亦是。
浮動(dòng)盒必須盡可能地往高擺放。
-
左浮動(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 屬性
該屬性指定元素的哪些側(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è)為下述中的較大值:
塊的邊框邊緣border edge與要被清除的最下方的浮動(dòng)的下外邊緣bottom outer edge不相交的必要高度。
將塊的上邊框邊緣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