通俗易懂的CSS布局display、position、float詳解


前端開發就像蓋房子,如果說 html 是構成房子的磚瓦, css 則是決定這些磚瓦的位置和對它們進行裝飾。在實際開發中,前端在拿到設計稿后,都會先梳理頁面的大致結構,構思完頁面的布局后,再進行 coding。大多數網站都有着相似的布局,掌握這些“套路”便可以快速高效的完成開發工作。

display

display 是 css 布局中很重要的一個屬性,它定義了元素生成的顯示框類型,常見的幾個屬性值有:blockinlineinline-blockinheritnoneflex。inherit 表示這個元素從父元素繼承 display 屬性值;none 表示這個元素不顯示,也不占用空間位置;flex 是 flex 布局重要的屬性設置,我們留到后面詳細講解,這邊先介紹前面三個屬性值。

每個元素都有默認的 display 屬性,比如 div 標簽的默認 display 屬性是 block,我們通常稱這類元素為塊級元素;span 標簽的默認 display 屬性是 inline,我們通常稱這類元素為行內元素,我們先通過下面的代碼示例來看下兩者的區別。

 
div布局結果
 
span布局結果

我們可以看到塊級元素總是獨占一行,從上到下顯示,行內元素則是從左到右顯示。這是因為塊級元素前后有換行符,而行內元素前后沒有換行符。除此之外,塊級元素和行內元素還有其他的區別和特性。

塊級元素:
沒有設置寬度時,它的寬度是其容器的 100%;
可以給塊級元素設置寬高、內邊距、外邊距等盒模型屬性;
塊級元素可以包含塊級元素和行內元素;
常見的塊級元素:<div><h1> ~ <h6><p><ul><ol><dl><table><address> <form> 等。

行內元素:
行內元素不會獨占一行,只會占領自身寬高所需要的空間;
給行內元素設置寬高不會起作用,margin 值只對左右起作用,padding 值也只對左右起作用;
行內元素一般不可以包含塊級元素,只能包含行內元素和文本;
常見的行內元素 <a><b><label><span><img><em><strong><i><input> 等。

細心的你可能會發現,給 img 標簽設置寬高是可以影響圖片大小的,這是因為 img 是可替代元素,可替代元素具有內在的尺寸,所以寬高可以設定。

html 中的 input、button、textarea、select 都是可替代元素,這些元素即使是空的,瀏覽器也會根據其標簽和屬性來決定顯示的內容。

給行內元素設置寬高不起作用,我們通過上面的代碼已經感受到了,那為什么設置 margin、padding 只有左右起作用呢?我們來看下面的列子。

 
在 span 標簽前后添加 div 標簽在瀏覽器中的運行結果

在上圖中可以明顯看到 span 1 只添加了 margin-left 和 margin-right,但 margin-top、margin-bottom 均不起作用。雖然上下的 padding 看上去都起作用了,但是通過添加 div 標簽,我們可以看到有重合的部分,所以 padding-top、padding-bottom 的設置從顯示效果上是增加的,但對周圍元素不會產生影響。

那 inline-block 又是什么呢?看命名方式,也能猜出大半,沒錯,設置為 inline-block 的元素,既具有塊級元素可以設置寬高的特性,又具有行內元素不換行的特性。我們給 div 標簽設置 inline-block 屬性看下效果。

 
將塊級元素的 display 屬性設置為 inline-block 后的效果

在上圖中,我們沒有設置 margin 值,但是 div 之間會有空隙,這是因為瀏覽器會將 html 中的換行符、制表符、空白符合並成空白符。

position(定位)

在布局中很重要的因素就是定位,position 屬性就是用來定義元素的定位機制。position 的常用屬性值有:

relative:相對定位,相對於元素的正常位置進行定位;
absolute:絕對定位,相對於除 static 定位以外的元素進行定位;
fixed:固定定位,相對於瀏覽器窗口進行定位,網站中的固定 header 和 footer 就是用固定定位來實現的;
static:默認值,沒有定位屬性,元素正常出現在文檔流中;
inherit:繼承父元素的 position 屬性值。

上文出現了文檔流(normal flow)的概念,按理來說應該翻譯成普通流,文檔流是大多數人的叫法。“流”可以想象成流動的水,當我們打開屏幕,瀏覽網頁,滾動鼠標,網頁的內容就像是水流一樣滑過。文檔流便是指從上到下,從左往右的文檔布局。當我們給元素的 positon 屬性設置 absolute、fixed 時便會脫離文檔流,不再遵循從上到下,從左到右的規律了。

1、relative
 
position 為 relative 示例

從上圖中我們不難發現,設置 position 為 relative,但是不添加額外屬性(left,right,top,bottom 等),它表現的如同 static 一樣,如 .box_1。屬性 left,right,top,bottom 會使元素偏離正常位置,如 .box_2。元素的偏移會覆蓋相鄰元素,如 .box_3。

2、absolute
 
position 為 absolute 示例

absolute 會相對於最近的除 static 定位以外的元素進行定位,在使用時要注意設置父元素(或祖先元素)的 position 屬性,若父元素(或祖先元素)都沒有設置定位屬性,absolute 會找到最上層即瀏覽器窗口,相對於它進行定位了。

3、fixed
 
position 為 fixed 示例

fixed 是相對於瀏覽器窗口的定位,一旦位置確定, 元素位置也不會改變,不像 absolute,它的位置與父元素息息相關,父元素移動它也會跟着動。從上圖我們可以看出,fixed 元素是脫離文檔流的,之后的元素會“無視”它,不會給它騰出空間。

float(浮動)

float 屬性定義元素在哪個方向浮動,常用屬性值有 left、right,即向左浮動和向右浮動。設置了 float 的元素,會脫離文檔流,然后向左或向右移動,直到碰到父容器的邊界或者碰到另一個浮動元素。塊級元素會忽略 float 元素,文本和行內元素卻會環繞它,所以 float 最開始是用來實現文字環繞效果的。

 
文字環繞效果

我們知道,當不給父元素設置寬高時,父元素的寬高會被子元素的內容撐開。但是當子元素設置浮動屬性后,子元素會溢出到父元素外,父元素的寬高也不會被撐開了,稱之為“高度塌陷”,我們通過代碼來體驗一下這個差異。

 
浮動的子元素不能撐開父元素

如何解決這個問題呢?解決這個問題便是要清除浮動,在下面我們給出了幾種常規解決方案。

清除浮動方案1:通過添加額外的標簽,利用 clear 屬性來清除浮動

clear 屬性用來定義哪一側不允許其他元素浮動,常見的值有 left 、right、both, 分別表示左側不允許浮動元素、右側不允許浮動元素、左右兩側均不允許浮動元素。

 
使用 clear: both 后把父元素撐開了
清除浮動方案2:使用 br 標簽

br 自帶 clear 屬性,clear 屬性有 left、right 和 all 三個屬性值可選。

 
 

該方法同上一個方法添加空標簽一樣,也達到了清除浮動的目的,同上一個方法相比,語義化明顯些了,但是也存在結構樣式行為分離的問題,不推薦使用。

清除浮動方案3:給父元素設置 overflow
 
image.png

添加 overflow 不僅減少了代碼量,還不存在語義化的問題,但是也可能因為內容增加導致超出尺寸的內容被隱藏。前面兩個方法帶有 clear 關鍵字,很好理解,但是僅僅設置 overflow: hidden; 為什么就能清除浮動呢?

這里要引入一個概念:BFC塊級格式化上下文。BFC 的一個特性便是可以包含浮動元素,設置 overflow 為 hidden 滿足了創建一個 BFC 的條件,其實就是創建 BFC,利用 BFC 固有特性清除浮動,這里不做過多講解,有興趣的伙伴可以查閱相關資料。

清除浮動方案4:使用 after 偽元素
 
 

該方法本質也是在末尾添加一個看不見的塊元素來清除浮動。這個方法也不存在語義化的問題,是目前的主流清除浮動的方法。



作者:反手一個function
鏈接:https://www.jianshu.com/p/914b76bae7b5
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM