CSS學習筆記:浮動屬性
一、浮動流是什麼
在css中,最常見的兩種流就是標準流和浮動了,其中標準流可以簡單如下理解:
- 塊級元素獨佔一行,且它們都可以設定對應的寬高(width和height),例如div,h標籤等
- 行內元素可以在一行中排列多個,它們的大小(寬度和高度)由裡面的內容所決定,常見的標籤有span,a標籤等
而浮動定位則是將元素排除在標準流之外,它的一些概念和特點如下:
- 將元素排除在普通流之外
- 元素將不在頁面中佔據空間
- 將浮動元素放置在包含框的左邊或者右邊
- 浮動元素依舊位於包含框之內
- 浮動的框可以向左或者向右移動,直到他的外邊緣碰到包含框或另一個浮動框的邊框為止
- 浮動元素的外邊緣不會超過其父元素的內邊緣
- 浮動元素不會互相重疊
- 浮動元素不會上下浮動【只能設定左右浮動】
- 任何元素一旦浮動,display 屬性將完全失效均可以設定寬高,並且不會獨佔一行
浮動語法:
#elem { float: none/left/right; }
二、通過程式碼例項瞭解浮動特點
1. 搭建測試框架
首先新建一個html檔案,body內容如下:
<div id="box">
<div></div>
<div></div>
<div></div>
</div>
對應的css:
#box { width: 600px; height: 600px; background: deeppink; } #box>div:first-child { width: 200px; height: 200px; background: green; } #box>div:nth-child(2) { width: 200px; height: 200px; background: aqua; } #box>div:nth-child(3) { width: 200px; height: 200px; background: red; }
此時的執行效果:
2. 新增浮動
此時如果給第一個元素新增浮動效果:
#box>div:first-child {
...
float: left;
}
可以看到第二個和第三個元素都向上移動了,且第二個元素被第一個元素遮住了,然後將浮動改為右浮動:
此時可以發現浮動的元素移動到了父元素的右邊界處。第2和第3個元素雖然都是獨佔一行的,但這並不會影響到浮動元素的排布。這裡可以理解為標準流中的元素都排列在地面上,而浮動的元素則是排列在空中的一層,因此地面元素佔用的位置不會影響空中元素的排列,此外浮動的元素會遮擋標準流中的元素,例如上面的藍色元素就被綠色元素遮擋住了。
3. 浮動元素的排布
我們先調節第三個div(紅色div)的大小:
#box>div:nth-child(3) {
width: 300px;
height: 300px;
...
}
然後為第二個元素也新增float: right
的浮動屬性,此時的效果為:
可以看到紅色的元素被遮擋住了,此時我們再為紅色元素也新增float: right
的浮動屬性:
可以看到紅色元素移動到了右下角,這是因為藍色元素左邊的位置已經不足以放下紅色元素了(剩餘位置的寬度<紅色元素的寬度),因此紅色元素只能向下尋找第一個可以放下的位置放置。
但如果紅色元素的寬高為200和400,即:
#box>div:nth-child(3) {
width: 200px;
height: 400px;
...
}
則它還是會被排布在藍色元素的左邊:
因此浮動元素是以寬度來判斷是否可以排布在當前位置的。
4. 給行內元素新增浮動效果
這裡先編寫兩個span元素:
<span class="floatSpan">我是span標籤</span>
<span class="floatSpan">我是span標籤</span>
對應的css:
.floatSpan {
background: red;
width: 100px;
height: 100px;
}
當前效果:
可以看到,當前設定的寬度和高度對它是無效的,因為行內元素的寬高只由它的內容大小決定。
然後為它新增float: left
的浮動效果:
.floatSpan {
...
float: left;
}
效果如下:
可以看到,當添加了浮動效果後,行內元素也可以設定寬高了,而且不會獨佔一行(和行內塊元素一樣),這驗證了【任何元素一旦浮動,display 屬性將完全失效均可以設定寬高,並且不會獨佔一行】這個浮動屬性的特點。
5. 子元素浮動後對父元素的影響
還是原來的#box
元素以及它的3個子元素,但此時我們去掉父元素的寬高設定(子元素先不浮動):
#box {
/* width: 600px;
height: 600px; */
background: deeppink;
}
此時的效果為:
可以看到,雖然我們沒有為父元素設定寬高,但預設情況下(標準流)父元素的高度會等於子元素的高度之和(也可以理解為子元素將父元素撐開)。
而如果此時我們為第一個元素新增右浮動,效果為:
這是因為綠色元素脫離了標準流,因此父元素就只能由剩下在標準流的子元素撐開了。依此類推,若三個元素均新增浮動,則不再有標準流中的元素將父元素撐開了,因此父元素的高度就會變為0,如下所示:
這也是我們使用浮動佈局橫向排列子元素經常會遇到的問題,有以下幾個辦法可以解決:
5.1 在父元素中新增overflow: hidden屬性
即:
#box {
/* width: 600px;
height: 600px; */
background: deeppink;
/* 在不設定寬高的情況下,讓父元素感知子元素的高度 */
overflow: hidden;
}
效果如下:
可以看到,父元素擁有了子元素的最大高度。
5.2 為父元素也新增浮動屬性
例如新增float: right
的浮動屬性:
#box {
/* width: 600px;
height: 600px; */
background: deeppink;
float: right;
}
可以看到父元素也得到了子元素的最大高度。
6. 消除浮動
例如上面的#box
可以看做是網頁中的一個專欄部分,當前希望在它的下面編寫一個新的專欄#new
,但#new
屬於標準流,而#box
添加了float: right
的浮動屬性,如果直接編寫則#new
會被#box
覆蓋,如下所示:
<div id="box">
...
</div>
<div id="new">
我是new專欄
</div>
#new {
height: 300px;
background: pink;
}
此時我們就需要消除上面div的浮動帶來的影響了,消除浮動有以下三種常用的方法。
6.1 在結尾處加上空的div標籤,新增clear: both屬性
<div id="box">
...
</div>
<div style="clear: both;"></div> <!--空的div標籤-->
<div id="new">
我是new專欄
</div>
效果如下:
同理,也可以在new中新增clear: both屬性:
#new {
...
clear: both;
}
效果也是相同的。
6.2 浮動元素父級div新增overflow: hidden屬性
上面5.1中也已經使用過了這個屬性,即可以使標準流中的div獲取浮動的子元素的高度,此時我們可以給#box
元素套一個#father
div,如下所示:
<div id="father">
<div id="box">...</div>
</div>
然後給father
新增overflow: hidden
屬性:
#father {
overflow: hidden;
}
效果如下:
可以發現這兩種方式的效果是一模一樣的。
6.3 給父元素指定寬高
這個方法應該是最笨的方法了,相當於給上面的father標籤指定它孩子的寬高,不過這個方法可以使用js進行實現。