掃二維碼與項(xiàng)目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
大家好,我是樹哥。

成都創(chuàng)新互聯(lián)公司成立于2013年,先為當(dāng)雄等服務(wù)建站,當(dāng)雄等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為當(dāng)雄企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
最近想著學(xué)習(xí)點(diǎn)前端知識,于是就學(xué)習(xí)了關(guān)于前端 Web 的布局知識,其實(shí)就是 CSS 那些事。關(guān)于 CSS 其實(shí)很早就接觸過了,但一直沒有沉下心來去學(xué)習(xí),所以對于 CSS 布局的東西一直都不成體系。這次趁著重學(xué)前端,真正花時間學(xué)了一下 CSS 布局的知識點(diǎn),順帶把知識點(diǎn)總結(jié)一下。
說到 CSS 布局,有寫過一些 CSS 頁面的同學(xué)腦海中可能會浮現(xiàn)一些字眼,例如:float、display、relative、absolute 等等。但這些屬性分別代表什么意思,它們之間都有什么區(qū)別,啥時候用 float 啥時候用 relative,你弄得懂嗎?對于我來說,我沒弄懂,有點(diǎn)懵。于是,我花了點(diǎn)時間弄懂它,這也是本文要重點(diǎn)弄懂的問題。簡單來說,看完這篇文章,你應(yīng)該可以弄清楚如下幾個問題:
1、常用的幾個 CSS 布局屬性作用及區(qū)別。
2、CSS 布局的歷史以及當(dāng)前流行的布局方式。
要注意的是,本文不會從零開始介紹 CSS 的知識點(diǎn)。只適合學(xué)習(xí)過 CSS,但是對 CSS 布局各種屬性沒弄明白的同學(xué)。如果你還沒學(xué)過 CSS 知識,那需要先去學(xué)習(xí)一下 CSS 基礎(chǔ)知識再來看這篇文章。
理解文檔流對于我們掌握 CSS 布局非常重要。簡單來說,我們在 HTML 中寫入的每一個元素,都是一個元素塊。默認(rèn)情況下,它們按照我們在 HTML 中書寫的順序,從上到下、從左到右排列,這就是默認(rèn)的文檔流。例如,對于如下所示的代碼片段,其在 HTML 中會按照順序顯示,如下圖所示。
段落1
段落2
段落3
在 CSS 布局中,有三個常用的 CSS 屬性,分別是:display、float、position。它們具有不同的功能,適用于不同的場景。
就像 display 的名字一樣,其用來定義元素塊的展示形式,不同的展示形式會有不同的展示效果。 display 屬性的常用屬性有:
要注意的是,不同的 HTML 元素,其默認(rèn)的展示形式是不同的。例如 p 元素(段落)的 display 屬性默認(rèn)值是 block,而 a 屬性(鏈接)的 display 屬性默認(rèn)值則是 inine。
下面,我們通過幾個簡單的例子來體會一下上面所說的內(nèi)容。如下圖所示的代碼,我們設(shè)置不同的 CSS 屬性,元素的展示形式會發(fā)生變化。
段落1
段落2
段落3
設(shè)置的 CSS 屬性如下所示:
.display {
background-color: red;
}顯示效果如下圖所示。
-w524
如上圖可以看到,在 CSS 代碼中,我只是設(shè)置背景顏色。由于 p 元素的默認(rèn) display 屬性值是 block,因此每個段落都會占用一行的空間。
如果我們把 p 元素設(shè)置成 inline 顯示形式,那么它們就會多個元素排列在一行內(nèi)。如下圖所示。
.display {
display: inline;
background-color: red;
/* width/height 屬性設(shè)置無效 */
width: 200px;
height: 200px;
}-w228
如果我們把 p 元素設(shè)置成 inline-block 顯示形式,并且設(shè)置了寬高,那么它們就會多個元素排列在一行內(nèi),并且寬高設(shè)置會生效。如下圖所示。
.display {
display: inline-block;
background-color: red;
/* width/height 屬性設(shè)置無效 */
width: 200px;
height: 200px;
}-w639
看到這里,相信大家應(yīng)該可以弄清楚 display 屬性的作用了。display 屬性其實(shí)就是用來設(shè)置 HTML 元素的展示形式的,不同的展示形式會有不同的展示效果。給不同的元素設(shè)置合適的屬性值,可以幫助我們更好地進(jìn)行頁布局。
display 屬性除了前面說得這三種屬性值之外,還有 flex、grid、table 等值。但目前用得最多的還是 flex 和 grid 這兩種,它們可以說是目前主流的 CSS 布局方式。關(guān)于這塊內(nèi)容,我們后面再細(xì)講,這里就不展開了。
就像 float 這個名字一樣,它代表著浮動。
啥意思呢?
要理解這個,就要從 CSS 的歷史說起了。很早之前,display 屬性只有兩個,分別是 block 和 inline。block 雖然支持設(shè)置寬高,但是不支持多個元素顯示在一行。inline 雖然支持多個元素顯示在一行,但是卻不能設(shè)置寬高。但是實(shí)際場景中,我們很多時候需要做多列布局的,即需要多個元素在同一行,并且同一行的元素都可以設(shè)置寬度,如下圖所示。
-w1173
這時候 CSS 就滿足不了我們的訴求了!
那怎么辦呢?
這時候 float 就橫空出世了!
簡單來說,float 就是讓塊級元素(block元素)浮起來。 塊級元素浮起來之后,塊級元素就不固定占用一行了,而是根據(jù)其設(shè)置的寬度顯示。如果一行的寬度能夠容納得下兩個浮動的塊級元素,那么它們就可以同時顯示在同一個行內(nèi)。
舉個簡單地例子,下面的 HTML 片段,設(shè)置了三個 block 元素塊。
段落1
段落2
段落3
.display {
display: block;
width: 200px;
height: 100px;
background-color: red;
}在沒有設(shè)置浮動之前,每個塊級元素都會占用一行,如下圖所示。
-w264
但是如果我們對元素設(shè)置了向左浮動,那么它們就會往左浮動,三個塊級元素都浮動到了同一行,如下圖所示。
.display {
display: block;
float: left;
width: 200px;
height: 100px;
background-color: red;
}-w626
所以,float 元素的出現(xiàn),是用來解決 block 元素塊無法同行顯示,從而無法實(shí)現(xiàn)特定布局場景的問題的。 在 float 出現(xiàn)的很長一段時間,基本上大家都靠 float 來進(jìn)行頁面布局。
有同學(xué)會問:好像 inline-block 也能實(shí)現(xiàn)這個效果呀?沒錯,inline-block 也能實(shí)現(xiàn)這樣的效果。但實(shí)際上,inline-block 是在 float 之后才出現(xiàn)的。 我猜,是 CSS 官方覺得:好像確實(shí)需要有這么一個屬性值,可以讓多個元素顯示在同一行,又可以設(shè)置它們的寬高。人民群眾既然需要,那么我們就搞一個 inline-block 給大家用吧!
但從回顧過去,貌似大家用 float 更多一些,用 inline-block 更少一些。為啥呢?或許是 inline-block 出現(xiàn)之前,大家都習(xí)慣用 float 了。而 inline-block 比起 float 貌似沒什么太大的改變,于是就沒動力去換了吧。
后來 CSS3 的 flex、grid 出現(xiàn)了,CSS 才真正有了一個非常好用的布局工具。到了 2023 年的今天,除非是一些需要兼容古老瀏覽器版本的頁面需要用 float 布局,其他大多數(shù)的 Web 頁面布局都使用 flex、grid 進(jìn)行布局了。
看到這里,信息量貌似有點(diǎn)大,怎么去理解 block -> float -> inline-block -> flex/grid 的這種布局變遷呢?知乎某前端大 V 賀師俊的理解,我覺得很好:
言歸正傳,CSS1時代的網(wǎng)頁還很簡陋,但是隨著萬維網(wǎng)的迅猛發(fā)展,Web界面也迅速進(jìn)化,當(dāng)初簡單的如同書頁般的通欄式網(wǎng)頁迅速絕跡,frameset由于天生存在的一堆問題也很快退出主流,這時CSS在GUI布局方面就顯出了缺陷,開發(fā)者被迫使用各種trick。比如歷史悠久的table布局。后來table布局被鄙視,開發(fā)者逐漸轉(zhuǎn)向了float布局。
要說float布局之所以流行,IE“功”不可沒。在IE中,has layout的元素是不會環(huán)繞float元素的(因?yàn)閔as layout的元素自己是一個控件,所以總是保持一個矩形區(qū)域)。這本來是一個bug,但是其效果卻正好符合常見的雙欄布局的需要。另外IE下float元素會自動撐開其父級container元素(當(dāng)然前提是container元素也是has layout的),這其實(shí)也是bug,但是也恰好符合模塊布局的需求。后來所謂inline-block布局其實(shí)正是這些bug的合理化。
站在今天回望過去十多年的CSS實(shí)踐,我們可以發(fā)現(xiàn),無論float布局還是后來的inline-block布局,其實(shí)都是trick。所謂trick,就是將一些特性挪作他用,以很曲折的方式實(shí)現(xiàn)出想要的效果。CSS作為樣式語言,其可維護(hù)性的最終來源,就是代碼能清晰的表達(dá)出設(shè)計意圖。而CSS trick當(dāng)然不能很好的滿足這一點(diǎn)。
簡單來說,這樣的布局方式變化,其實(shí)是 CSS 不斷完善進(jìn)化的結(jié)果。一開始的時候,CSS 的功能比較簡陋,所以需要我們自己用各種 trick 來實(shí)現(xiàn)需要的功能。到了后面,各種應(yīng)用場景日趨完善,CSS 也不斷完善起來,最終我們可以用很簡單的 flex、grid 就實(shí)現(xiàn)之前所需要的效果。
以上關(guān)于 CSS 變遷的理解,來自于賀師俊的知乎回答,感興趣的同學(xué)可以點(diǎn)擊查看原文:在 CSS 中,用 float 和 position 的區(qū)別是什么?- 賀師俊的回答 - 知乎
如 position 名字的意思一樣,position 主要是用來調(diào)整元素位置用的。一般情況下,我們用 display 和 float 做好布局之后,可能需要對元素做一些微調(diào),那么這時候就該 position 登場了。對于 position 來說,其有五個屬性值,分別是:static、relative、absolute、fixed、sticky。
static 關(guān)鍵字指定元素使用正常的布局行為,即元素在文檔常規(guī)流中當(dāng)前的布局位置。
如下圖所示的 HTML 片段,我們不設(shè)置 position 屬性,或者設(shè)置 position 屬性為 static,其展示形式都不發(fā)生變化。
.parent{
width: 200px;
height: 200px;
border: 1px solid red;
}
.box {
position: static;
width: 50px;
height: 50px;
background-color: black;
}-w241
relative 表示相對定位,即相對于其父級容器做偏移。偏移位置使用 left/right/top/bottom 屬性來設(shè)置。就如上面的例子中,如果我們使用如下的 CSS 設(shè)置,我們可以看到對應(yīng)的塊元素相對父容器做了偏移,如下圖所示。
.parent{
width: 200px;
height: 200px;
border: 1px solid red;
}
.box {
position: relative;
left: 20px;
top: 20px;
width: 50px;
height: 50px;
background-color: black;
}-w232
absolute 表示絕對定位。元素會被移出正常文檔流,并不為元素預(yù)留空間。通過指定元素相對于最近的非 static 定位祖先元素的偏移,來確定元素位置。絕對定位的元素可以設(shè)置外邊距(margins),且不會與其他邊距合并。
如下所示的 HTML 片段,我們使用如下的 CSS 設(shè)置進(jìn)行設(shè)置,那么對應(yīng)元素塊(box類所在元素)的偏移原點(diǎn)就不是其父級元素(son類所在元素),而是最頂層的非 static 定義的祖先元素了(parent類所在元素),如下圖所示。
.parent{
position: relative;
top: 50px;
left: 800px;
width: 300px;
height: 200px;
border: 1px solid red;
}
.son {
top: 30px;
left: 30px;
width: 100px;
height: 100px;
border: 1px solid black;
}
.box {
position: absolute;
left: 20px;
top: 20px;
width: 50px;
height: 50px;
background-color: black;
}-w1245
fixed 也表示絕對定位。元素會被移出正常文檔流,并不為元素預(yù)留空間,而是通過指定元素相對于屏幕視口(viewport)的位置來指定元素位置。元素的位置在屏幕滾動時不會改變。其與 absolute 的區(qū)別是,fixed 是相對于屏幕 viewport 做偏移的,而 absolute 是相對于最近的一個非 static 祖先元素做偏移的。
如下所示的 HTML 代碼塊,其與上面 absolute 屬性里的代碼塊完全一致,我們只是將 box 類的 position 屬性值改為了 fixed,如下代碼所示。
.parent{
position: relative;
top: 50px;
left: 800px;
width: 300px;
height: 200px;
border: 1px solid red;
}
.son {
top: 30px;
left: 30px;
width: 100px;
height: 100px;
border: 1px solid black;
}
.box {
position: fixed;
left: 20px;
top: 20px;
width: 50px;
height: 50px;
background-color: black;
}其展示的效果如下圖所示。
-w1184
從這里我們可以較為清晰地看出 absolute 和 fixed 兩個屬性值的區(qū)別。
sticky 表示粘性布局,其可以被認(rèn)為是相對定位和固定定位的混合。元素在跨越特定閾值前為相對定位,之后為固定定位。例如:
#one {
position: sticky;
top: 10px;
}上面的代碼表示:在 viewport 視口滾動到元素 top 距離小于 10px 之前,元素為相對定位。等到距離小于 10px 之后,元素將變?yōu)?fixed 定位,元素將固定在與 viewport 頂部距離 10px 的位置。直到元素與 viewport 頂部的距離再次大于 10px,將再次變成相對定位。
一般情況下,這個用于一些滾動查看文本時,需要將某些信息置頂再頂部的情況,如下圖所示。
圖片
在 sticky 屬性之前,我們需要自己做很復(fù)雜的設(shè)置才能實(shí)現(xiàn)這樣的效果。但 sticky 屬性直接幫我們實(shí)現(xiàn)了,非常方便。
看到這里,我們基本上把 CSS 布局所需要了解的知識點(diǎn)都介紹了一遍。那我們在實(shí)現(xiàn) Web 頁面的時候,到底應(yīng)該用哪些 CSS 屬性呢?是 float + block,還是 inlien-blcok,亦或是 flex 呢?
這里我直接給出答案:如果沒有歷史負(fù)擔(dān),不需要去兼容老版本瀏覽器,那么直接上 flex/grid 布局。如果要兼容古老的瀏覽器版本,那么就先用 float,float 解決不了就用 position。
為啥是這樣呢?以為 flex 和 grid 布局是最新的 CSS3 提供的解決方案,是對之前 float + display + position 的總結(jié),是更好的工具。但缺點(diǎn)也明顯,就是一些老版本瀏覽器不兼容,沒法使用。因此要兼容老版本瀏覽器的話,就只能用老古董的 float 這種 tricks 了。
如果你需要用 float 這種方式去做布局,那可以參考一下這篇文章:【CSS】CSS布局解決方案(終結(jié)版) - 掘金。文章里列舉了不少布局方式,還是比較實(shí)用的,讓你快速掌握常用的布局方式。
我把文章中涉及到的例子都整理到了 CodePen 上,方便大家嘗試,有需要的可以看看:https://codepen.io/Ronald-Chan/pen/wvRdBGL
對于 flex 布局來說,其使用也非常簡單,基本上把對應(yīng)的屬性看一篇就知道怎么玩了。不像 float 布局一樣,需要思來想去的,非常麻煩。
考慮到問文章篇幅和主題問題,關(guān)于如何使用 flex、grid 進(jìn)行排版布局,這里就不延展展開了,后續(xù)有機(jī)會再分享 flex 布局相關(guān)內(nèi)容。
對于 CSS 布局,之前自己只粗淺地知道 float、display 這些屬性,并沒有深入對比彼此的區(qū)別。當(dāng)然也沒有去了解這些屬性背后的 CSS 發(fā)展歷程,于是很多時候都會被弄暈。
但這次通過將屬性之間進(jìn)行對比,再深入了解了一下 CSS 的發(fā)展歷程,對 CSS 布局的知識有了整體的了解。知道過去用的是什么方式布局,現(xiàn)在及未來要用什么方式布局,對 CSS 布局就更有底了。
對于 CSS 布局來說,float 方式的布局慢慢會被淘汰,因此不必花大力氣去學(xué)習(xí),只在有需要的時候?qū)W習(xí)一下就好。我們的學(xué)習(xí)重點(diǎn)應(yīng)該放在 flex、grid 等布局方式的學(xué)習(xí),這也是我后續(xù)的學(xué)習(xí)方向。
關(guān)于 CSS 布局知識的分享就到此為止。希望這篇文章也能給你帶來收獲,讓你更好掌握 CSS 布局技能。如果這篇文章對你有幫助,記得一鍵三連支持我!

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流