浮動 float
浮動元素 ( float ) 一直都是網頁排版的主要技巧,這篇教學除了會介紹 float 屬性的語法,也會深入探討浮動元素和 inline 元素與 block 元素在排版的互動或換行情況,以及 clear 清除浮動的屬性語法。
快速導覽:
float 撰寫語法
要將元素變成浮動元素,需要使用「float
」屬性,沒有繼承特性,屬性值有下列幾種:
屬性值 | 說明 |
---|---|
left | 靠左浮動 |
right | 靠右浮動 |
none | 不浮動 ( 預設值 ) |
下方範例分別將行內元素 oxxo 設為靠左浮動和靠右浮動。
<!-- HTML 程式碼-->
沒有浮動元素
<div class="a">
<span>apple</span><span class="f">oxxo</span><span>banana</span><span>orange</span>
</div>
浮動元素靠左浮動
<div class="b">
<span>apple</span><span class="f">oxxo</span><span>banana</span><span>orange</span>
</div>
浮動元素靠右浮動
<div class="c">
<span>apple</span><span class="f">oxxo</span><span>banana</span><span>orange</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
padding: 10px;
margin: 10px;
}
span {border: 1px solid #aaa;}
.f {color: red;}
.b .f {float: left;} /* 設定靠左浮動 */
.c .f {float: right;} /* 設定靠右浮動 */
</style>
認識「float 浮動」
所謂的「浮動元素」,基本上都具備下列行為:
- 浮動元素不論原本顯示類型為何,一率轉換成「block 顯示類型」元素,且無法透過任何方式修改顯示類型。
- 浮動元素在沒有設定尺寸的狀態下,使用內容尺寸作為長寬尺寸。
- 浮動元素會「離開原本所在的平面」,移動到「浮動元素所在的平面」,排版不會受到原本平面的排版規則限制。
- 浮動元素會根據設定向左或向右移動,直到「碰到父元素邊緣或其他浮動元素」,移動範圍限制在父元素的容器內容範圍。
- 浮動元素所佔的「內容」空間會影響原本平面上內容,造成其他元素的「內容」發生位移。
以下圖為例,如果畫面中有 ABCD 四個行內元素 ( 顯示類型為 inline ),當 C 元素設為浮動之後,C 元素會移動到浮動的平面,根據設定靠左或靠右浮動,C 元素的內容會佔據原本平面上的內容空間,將其他元素的內容推擠到其他位置。
如果將上圖轉換為程式碼,變成浮動元素的 span,就會移動到左方或是右方。
<!-- HTML 程式碼-->
沒有浮動元素
<div class="a">
<span>apple</span><span class="f">oxxo</span><span>banana</span><span>orange</span>
</div>
有浮動元素,靠左浮動
<div class="b">
<span>apple</span><span class="f">oxxo</span><span>banana</span><span>orange</span>
</div>
有浮動元素,靠右浮動
<div class="c">
<span>apple</span><span class="f">oxxo</span><span>banana</span><span>orange</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
padding: 10px;
margin: 10px;
}
span {border: 1px solid #aaa; }
.f {color: red;}
.b .f {float: left;} /* 設定靠左浮動 */
.c .f {float: right;} /* 設定靠左浮動 */
</style>
多個浮動元素,按照先後順序排列
如果有兩個以上的浮動元素,會按照元素在程式碼中的先後順序,依循下方的規則進行排列:
- 後方的浮動元素水平位置不會超過前方的浮動元素。
- 後方的浮動元素垂直高度不會高於前方的浮動元素。
以下圖為例,畫面中 ABCD 四個行內元素,當 B 和 D 元素設為浮動之後,B 元素會先往左或往右移動到邊緣,接著 D 元素再往左或往右直到碰到 B 元素為止。
如果將上圖轉換為程式碼,變成浮動元素的兩個 span,就會移動到左方或是右方。
<!-- HTML 程式碼-->
沒有浮動元素
<div class="a">
<span>apple</span><span class="f">banana</span><span>oxxo</span><span class="f">orange</span>
</div>
有浮動元素,靠左浮動
<div class="b">
<span>apple</span><span class="f">banana</span><span>oxxo</span><span class="f">orange</span>
</div>
有浮動元素,靠右浮動
<div class="c">
<span>apple</span><span class="f">banana</span><span>oxxo</span><span class="f">orange</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
padding: 10px;
margin: 10px;
}
span {border: 1px solid #aaa;}
.f {color: red;}
.b .f {float: left;} /* 設定靠左浮動 */
.c .f {float: right;} /* 設定靠左浮動 */
</style>
浮動元素與 inline 元素的換行情境
如果浮動元素和顯示類型為 inline 的元素進行互動,大部分排版的情形都滿容易理解 ( 上述的範例都使用 inline 元素進行互動 ),但有時會發生「換行」的狀況,這也是最困擾使用者的地方,由於浮動元素和 inline 元素位置都是使用「內容」空間,會在下列情況發生推擠內容而換行的狀況:
- 浮動元素前方 inline 元素的「容器空間」無法容納浮動元素 ( 沒有標籤包覆的匿名元素也存在容器空間 )。
下圖呈現浮動元素和 inline 元素的互動狀況,當浮動元素 B 前方的 A 元素空間還能容納 B 時,B 就會按照浮動元素靠左的方式放在左側,但如果浮動元素 C 超過 A 元素單行的空間,就會換行到第二行,並遵守不超過 B 的規則,就會放在 B 右下方的位置。
下方使用程式碼呈現浮動元素和 inline 元素互動後換行的情境。
<!-- HTML 程式碼-->
沒有浮動元素
<div class="a">
<span>apple1 apple2 apple3</span> <span class="f">banana</span> <span class="f">oxxo</span> <span>orange</span>
</div>
浮動元素靠左浮動
<div class="b">
<span>apple1 apple2 apple3</span> <span class="f">banana</span> <span class="f">oxxo</span> <span>orange</span>
</div>
浮動元素靠左浮動,第一行文字很長
<div class="c">
<span>apple1 apple2 apple3 apple4</span> <span class="f">banana</span> <span class="f">oxxo</span> <span>orange</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
padding: 10px;
margin: 10px;
width: 230px;
}
span {border: 1px solid #aaa;}
.f {
color: red;
border: 1px solid #f00;
}
.b .f {float: left;} /* 設定靠左浮動 */
.c .f {float: left;} /* 設定靠左浮動 */
</style>
浮動元素與 block 元素的換行情境
如果浮動元素和顯示類型為 block 的元素放在一起,則會延伸出下列的規則:
- 浮動元素排列時最高的位置,不能高過「前方的」block 元素。
- 浮動元素會佔據 block 元素的「內容」空間,但不會佔據 block 元素的「盒子」空間,換句話說就是 block 元素的內容會被推擠造成位移或換行,但 block 元素的盒子位置不會被改變。
以下圖為例,畫面中 ABCD 四個 block 元素,當 C 元素設為浮動之後,最高的位置不會超過 B 元素,且不會影響 D 元素的盒子容器外觀 ( 因為 C 元素完全離開平面 ),但因為 C 元素的內容空間會影響 D 元素的內容,造成 D 元素內容發生位移 ( D 元素的灰色盒子空間不變,但綠色的內容空間被推擠到旁邊 )。
下方範例將 block 元素加上灰色邊框,浮動元素加上紅色邊框,呈現的結果可以發現浮動元素不會影響 block 元素的盒子容器,但內容卻會擠壓 block 容器的內容文字,造成內容文字位移。
<!-- HTML 程式碼-->
沒有浮動元素
<div class="a">
<span>apple</span><span>banana</span><span class="f">oxxo</span><span>orange</span>
</div>
有浮動元素,靠左浮動
<div class="b">
<span>apple</span><span>banana</span><span class="f">oxxo</span><span>orange</span>
</div>
有浮動元素,靠右浮動
<div class="c">
<span>apple</span><span>banana</span><span class="f">oxxo</span><span>orange</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
padding: 3px;
margin: 10px;
}
span {
display: block; /* 設定為 block 顯示類型 */
border: 1px solid #aaa; /* 設定灰色邊框凸顯盒子容器 */
padding: 3px;
}
.f {
color: red;
border: 1px solid #f00; /* 設定紅色邊框凸顯浮動元素 */
padding: 0;
}
.b .f {float: left;} /* 設定靠左浮動 */
.c .f {float: right;} /* 設定靠左浮動 */
</style>
浮動元素和 block 元素互動時,「換行」往往是最困擾使用者排版的問題,由於浮動元素和一般元素的位置使用的是「內容」空間,所以會在下列情況發生推擠內容而換行的狀況:
- 浮動元素前方出現 block 元素造成強制換行。
- 浮動元素後方的 block 元素內容過長,後方內容會換行。
- 多個浮動元素如果位於不同行,後方的浮動元素仍然會遵守浮動元素的順序,位置不會超過前方浮動元素。
下圖呈現浮動元素和 block 元素的互動狀況,當浮動元素 C 後方的 D 元素空間能夠同時容納 C 和 D 的內容時,C 就會按照浮動元素靠左的方式放在左側並將 D 的內容推擠到旁邊,但如果 D 的空間不足時,D 的內容就會發生換行的現象,但 C 的內容仍然會佔據 D 元素的容器空間。
下方使用程式碼呈現浮動元素和 block 元素互動後換行的情境,可以看清楚地看浮動元素造成其他內容的換行,出並非是「容器」換行,而是容器裡的「內容」發生換行。
<!-- HTML 程式碼-->
沒有浮動元素
<div class="a">
<span>apple</span> <span>banana</span> <span class="f">oxxo</span> <span>orange</span>
</div>
浮動元素靠左浮動,寬度自動
<div class="b">
<span>apple1 apple2 apple</span> <span>banana</span> <span class="f">oxxo</span> <span>orange</span>
</div>
浮動元素靠左浮動,設定比較小的寬度
<div class="c">
<span>apple</span> <span>banana</span> <span class="f">oxxo</span> <span>orange</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
padding: 3px;
margin: 10px;
width: 230px;
}
span {
display: block; /* 改成 block 顯示類型 */
border: 1px solid #aaa;
padding: 5px; /* 加上 padding 區隔浮動元素 */
}
.c span {width: 100px;} /* 設定比小的寬度 */
.f {
color: red;
padding: 0;
border: 1px solid #f00;
}
.b .f {float: left;} /* 設定靠左浮動 */
.c .f {float: left;} /* 設定靠左浮動 */
</style>
此外,要記得如果多個浮動元素中穿插了 block 元素,前方是 block 元素的浮動元素仍然會發生「換行」的狀況,下方的範例呈現多個浮動元素穿插在 block 元素之間的情形。
<!-- HTML 程式碼-->
<div>
<span>apple</span> <span class="f">banana</span> <span>milk</span> <span class="f">oxxo</span> <span>orange</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
padding: 3px;
margin: 10px;
width: 250px;
}
span {
display: block;
border: 1px solid #aaa;
padding: 5px;
}
.f {
float: left; /* 靠左浮動 */
color: red;
padding: 0;
border: 1px solid #f00;
}
</style>
浮動的重疊
當一般的元素透過 float
變成浮動元素後,浮動元素彼此之間不重疊,和其他一般元素也不會重疊,和父元素的邊界也不會重疊,但如果將「maring 外邊界」設為「負值」,則會因為外邊界內縮造成重疊的效果 ( 參考「margin 設定負值」)。
當浮動元素與 inline 元素重疊時,inline 元素的「邊框、背景和內容」都會「在浮動元素的上層」,從下方範例可以看出,雖然浮動元素在 HTML 程式碼中順序在第一個元素之上,但因為是浮動元素與 inline 元素的重疊行為,導致第一個元素反而覆蓋了浮動元素。
<!-- HTML 程式碼-->
純 inline 元素
<div class="a">
<span>apple</span> <span>banana</span> <span class="f">oxxo</span> <span>orange</span>
</div>
浮動元素 + inline 元素
<div class="b">
<span>apple</span> <span>banana</span> <span class="f">oxxo</span> <span>orange</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #aaa;
padding: 3px;
margin: 10px;
width: 280px;
}
span {
border: 1px solid #000;
padding: 10px;
background: #ccc;
}
.f {
margin: -10px;
color: red;
border: 1px solid #f00;
background: #f003;
}
.b .f {float: left;}
</style>
當浮動元素與 block 元素重疊時,block 元素的「邊框、背景和內容」都會「在浮動元素的下層」,從下方範例可以看出,雖然浮動元素在 HTML 程式碼中順序在第四個元素之下,但因為是浮動元素與 block 元素的重疊行為,導致浮動元素覆蓋了第四個元素。
<!-- HTML 程式碼-->
純 block 元素
<div class="a">
<span>apple</span> <span>banana</span> <span class="f">oxxo</span> <span>orange</span>
</div>
浮動元素 +block 元素
<div class="b">
<span>apple</span> <span>banana</span> <span class="f">oxxo</span> <span>orange</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #aaa;
padding: 3px;
margin: 10px;
width: 280px;
}
span {
display: block;
border: 1px solid #000;
padding: 10px;
background: #ccc;
}
.f {
margin: -10px;
color: red;
border: 1px solid #f00;
background: #f003;
}
.b .f {float: left;}
</style>
clear 清除浮動
當元素變成浮動元素後,元素的「內容空間」會直接影響前後元素的排版,內容空間對於 inline 行內元素而言影響比較小 ( 原本大多都是用內容排版 ),但如果是對於 block 區塊元素而言,有時會造成版面的混亂 ( 內容和容器空間分不清楚 ),如果希望 block 區塊類型的元素不要被浮動元素被影響,可以使用「clear
」清除浮動的樣式屬性,將 block 元素宣告不受浮動元素影響,清除浮動的屬性值如下:
注意,
clear
只針對 block 顯示類型元素有作用,且沒有繼承特性。
屬性值 | 說明 |
---|---|
both | 不受向左或向右浮動元素影響。 |
left | 不受向左浮動元素影響。 |
right | 不受向右浮動元素影響。 |
none | 會被浮動元素影響 ( 預設值 )。 |
下方範例有三個區塊,第一個區塊呈現完全不清除浮動的情形 ( banana 和 oxxo 會根據浮動規則擺放 ),第二個區塊設定 clear:right
,因此會清除浮動向右的浮動元素影響,milk 元素就不會受到 banana 元素影響,但由於 oxxo 元素是浮動向左,仍然會影響到 orange 的內容,第三個區塊因為是 clear:both
,會同時清除向左向右浮動,因此區塊的內容就都不會被浮動影響。
<!-- HTML 程式碼-->
<div class="a">
<div>apple</div> <div class="fr">banana</div> <div>milk</div> <div class="fl">oxxo</div> <div>orange</div>
</div>
<div class="b">
<div>apple</div> <div class="fr">banana</div> <div class="cc">milk ( clear: right )</div> <div class="fl">oxxo</div> <div class="cc">orange ( clear: right )</div>
</div>
<div class="c">
<div>apple</div> <div class="fr">banana</div> <div class="cc">milk ( clear: both )</div> <div class="fl">oxxo</div> <div class="cc">orange ( clear: both )</div>
</div>
<!-- CSS 程式碼 -->
<style>
.a, .b, .c {
border: 1px solid #000;
padding: 3px;
margin: 10px;
}
div div {
border: 1px solid #aaa;
margin: 5px;
}
.fr, .fl {
color: red;
padding: 0;
border: 1px solid #f00;
}
.fr {float: right;} /* 向右浮動 */
.fl {float: left;} /* 向左浮動 */
.b .cc {clear: right;} /* 清除向右浮動 */
.c .cc {clear: both;} /* 清除向左浮動 */
</style>
小結
float 浮動是網頁排版裡的重要技巧,但也是相當容易搞錯用法的樣式屬性,使用時只要記住浮動元素影響的是「內容」而不是「容器」,就可以得心穎手的去應用浮動元素囉。
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~