在使用 CSS float 屬性進行排版時,一個常見但容易忽略的問題是:當浮動元素前面有其他元素時,浮動元素可能不會出現在預期的位置,而是被擠到下一行。
float 的基本行為
float 屬性讓元素脫離正常文件流(Normal Flow),使其向左或向右浮動,而後續的行內內容(文字、inline 元素)會環繞在浮動元素旁邊。
1
2
3
4
|
.float-box {
float: left;
width: 200px;
}
|
前面有 Block 元素時的問題
當浮動元素前面有一個 display: block 的元素時,block 元素會佔據整行,導致浮動元素從新的一行開始浮動:
1
2
3
|
<div class="block-element">我是 Block 元素,佔滿整行</div>
<div class="float-box">我想浮到左邊</div>
<div class="float-box">我也想浮到左邊</div>
|
1
2
3
4
5
6
7
8
9
10
11
12
|
.block-element {
/* display: block 是預設值,佔滿整行 */
background: #eee;
padding: 10px;
}
.float-box {
float: left;
width: 150px;
height: 100px;
background: #ccc;
margin: 5px;
}
|
由於 .block-element 佔滿整行,兩個浮動框只能從它下方開始排列。
前面有 Inline 元素的影響
如果浮動元素前面有行內元素(inline element),那個行內元素的高度會影響浮動元素的起始位置,造成意外的換行。
解決浮動影響佈局的方法
方法一:Clearfix(清除浮動)
這是最經典的解法,讓父容器能夠包含浮動的子元素:
1
2
3
4
5
6
|
/* clearfix hack */
.clearfix::after {
content: "";
display: table;
clear: both;
}
|
1
2
3
4
5
|
<div class="container clearfix">
<div class="float-box">左浮動</div>
<div class="float-box">左浮動</div>
</div>
<!-- clearfix 讓 container 能包住浮動元素 -->
|
方法二:在需要清除浮動的地方加 clear
1
2
3
|
.clear-element {
clear: both; /* left, right, 或 both */
}
|
方法三:父元素設定 overflow: hidden 或 overflow: auto
1
2
3
|
.container {
overflow: hidden; /* 觸發 BFC,包含浮動元素 */
}
|
方法四:改用 Flexbox(現代推薦做法)
1
2
3
4
|
.container {
display: flex;
flex-wrap: wrap;
}
|
Flexbox 不存在浮動影響佈局的問題,是現代 CSS 排版的首選方案。
視覺示意
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
【有 float 但沒有 clearfix 時】
┌─────────────────────┐
│ Block 元素(佔滿行) │
└─────────────────────┘
┌──────┐┌──────┐
│float ││float │ ← 浮動在 block 下方
└──────┘└──────┘
↑ 父容器高度為 0(無法包住浮動元素)
【使用 clearfix 後】
┌─────────────────────┐
│ ┌──────┐┌──────┐ │
│ │float ││float │ │ ← 父容器正確包住浮動元素
│ └──────┘└──────┘ │
└─────────────────────┘
|
參考資料