本文將講述 CSS 中最核心的幾個概念承边,包括:盒模型、position毡鉴、float等崔泵。這些是 CSS 的基礎(chǔ),也是最常用的幾個屬性猪瞬,它們之間看似獨立卻又相輔相成憎瘸。為了掌握它們,有必要寫出來探討一下陈瘦,如有錯誤歡迎指正幌甘。
元素類型
HTML 的元素可以分為兩種:
- 塊級元素(block level element)
- 內(nèi)聯(lián)元素(inline element 有的人也叫它行內(nèi)元素)
兩者的區(qū)別在于以下三點:
- 塊級元素會獨占一行(即無法與其他元素顯示在同一行內(nèi),除非你顯示修改元素的 display 屬性),而內(nèi)聯(lián)元素則都會在一行內(nèi)顯示含潘。
- 塊級元素可以設(shè)置 width、height 屬性线婚,而內(nèi)聯(lián)元素設(shè)置無效遏弱。
- 塊級元素的 width 默認為 100%,而內(nèi)聯(lián)元素則是根據(jù)其自身的內(nèi)容或子元素來決定其寬度塞弊。
最常見塊級元素應(yīng)該是 <div>
吧漱逸,內(nèi)聯(lián)元素有 <span>
<a>
<img>
等等,完整的元素列表可以谷歌一下游沿。
具體來說一下吧,
.example {
width: 100px;
height: 100px;
}
我們?yōu)?<div>
設(shè)置上面的樣式饰抒,是有效果的,因為其是塊級元素诀黍,而對 <span>
設(shè)置上面的樣式是沒用的袋坑。要想讓 <span>
也可以改變寬高,可以通過設(shè)置 display: block;
來達到效果眯勾。當 display 的值設(shè)為 block 時枣宫,元素將以塊級形式呈現(xiàn);當 display 值設(shè)為 inline 時吃环,元素將以內(nèi)聯(lián)形式呈現(xiàn)也颤。
若既想讓元素在行內(nèi)顯示,又能設(shè)置寬高郁轻,可以設(shè)置:
display: inline-block;
inline-block 在我看來就是讓元素對外呈內(nèi)聯(lián)元素翅娶,可以和其他元素共處與一行內(nèi);對內(nèi)則讓元素呈塊級元素好唯,可改變其寬高竭沫。
HTML 代碼是順序執(zhí)行的,一份無任何 CSS 樣式的 HTML 代碼最終呈現(xiàn)出的頁面是根據(jù)元素出現(xiàn)的順序和類型排列的骑篙。塊級元素就從上到下排列输吏,遇到內(nèi)聯(lián)元素則從左到右排列。這種無樣式的情況下替蛉,元素的分布叫普通流贯溅,元素出現(xiàn)的位置應(yīng)該叫正常位置(這是我瞎起的),同時所有元素會在頁面上占據(jù)一個空間躲查,空間大小由其盒模型決定它浅。
盒模型
頁面上顯示的每個元素(包括內(nèi)聯(lián)元素)都可以看作一個盒子,即盒模型( box model )镣煮。請看Chrome DevTools 里的截圖:
可以顯而易見的看出盒模型由 4 部分組成姐霍。從內(nèi)到外分別是:
content -> padding -> border -> margin
按理來說一個元素的寬度(高度以此類推)應(yīng)該這樣計算:
總寬度 = margin-left + border-left + padding-left + width + padding-right + border-right + margin-right
但是不同瀏覽器(你沒有猜錯,就是那個與眾不同的瀏覽器)對寬度的詮釋不一樣。符合 W3C 標準的瀏覽器認為一個元素的寬度只等于其 content 的寬度镊折,其余都要額外算胯府。于是你規(guī)定一個元素:
.example {
width: 200px;
padding: 10px;
border: 5px solid #000;
margin: 20px;
}
則他最終的寬度應(yīng)為:
寬度 = width(200px) + padding(10px * 2) + border(5px * 2) + margin(20px * 2) = 270px;
而在 IE(低于IE9) 下,最終寬度為:
寬度 = width(200px) + margin(20px * 2) = 240px;
我個人覺得 IE 的更符合人類思維恨胚,畢竟 padding 叫內(nèi)邊距骂因,邊框算作額外的寬度也說不下去。W3C 最后為了解決這個問題赃泡,在 CSS3 中加了 box-sizing 這個屬性寒波。當我們設(shè)置 box-sizing: border-box;
時,border 和 padding 就被包含在了寬高之內(nèi)升熊,和 IE 之前的標準是一樣的俄烁。所以,為了避免你同一份 css 在不同瀏覽器下表現(xiàn)不同级野,最好加上:
*, *:before, *:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
這里還有兩種特殊情況:
- 無寬度 —— 絕對定位(position: absolute;) 元素
- 無寬度 —— 浮動(float) 元素
它們在頁面上的表現(xiàn)均不占據(jù)空間(脫離普通流页屠,感覺像浮在頁面上層一樣,移動它們不影響其他元素的定位)蓖柔。這就涉及到另外兩個核心概念 position 和 float卷中。
position
position 這個屬性決定了元素將如何定位。它的值大概有以下五種:
position 值 | 如何定位 |
---|---|
static | position的默認值渊抽。元素將定位到它的正常位置(上文提到過)蟆豫,其實也就相當于沒有定位。元素在頁面上占據(jù)位置懒闷。不能使用 top right bottom left 移動元素位置十减。 |
relative | 相對定位,相對于元素的正常位置來進行定位愤估。元素在頁面占據(jù)位置帮辟。可以使用 top right bottom left 移動元素位置。 |
absolute | 絕對定位玩焰,相對于最近一級的 定位不是 static 的父元素來進行定位由驹。元素在頁面不占據(jù)位置。 可以使用 top right bottom left 移動元素位置昔园。 |
fixed | 絕對定位蔓榄,相對于瀏覽器窗口來進行定位。其余和 absolute 一樣默刚,相當于一種特殊的 absolute甥郑。 |
inherit | 從父元素繼承 position 屬性的值。 |
具體效果可以參考w3school的實例荤西,或者自己寫一下就明白了澜搅。
每個網(wǎng)頁都可以看成是由一層一層頁面堆疊起來的伍俘,如下圖所示。
position 設(shè)置為 relative 的時候勉躺,元素依然在普通流中癌瘾,位置是正常位置,你可以通過 left right 等移動元素饵溅。會影響其他元素的位置妨退。
而當一個元素的 position 值為 absolute 或 fixed 的時候,會發(fā)生三件事:
- 把該元素往 Z 軸方向移了一層概说,元素脫離了普通流碧注,所以不再占據(jù)原來那層的空間嚣伐,還會覆蓋下層的元素糖赔。
- 該元素將變?yōu)閴K級元素,相當于給該元素設(shè)置了
display: block;
(給一個內(nèi)聯(lián)元素轩端,如<span>
放典,設(shè)置 absolute 之后發(fā)現(xiàn)它可以設(shè)置寬高了)。 - 如果該元素是塊級元素基茵,元素的寬度由原來的 width: 100%(占據(jù)一行)奋构,變?yōu)榱?auto。
由此觀之拱层,當 position 設(shè)置為 absolute 或 fixed弥臼,就沒必要設(shè)置 display 為 block 了。而且如果你不想覆蓋下層的元素根灯,可以設(shè)置 z-index 值 達到效果径缅。
float
float 顧名思義,就是把元素浮動烙肺,它的取值一共有四個:left right none inherit纳猪,光看名字就懂了,無需多言桃笙。
最初的 float 只是用來實現(xiàn)文字環(huán)繞圖片的效果氏堤,僅此而已。而現(xiàn)在 float 的應(yīng)用已不止這個搏明,前輩們也是寫了無數(shù)博文來深入淺出的講解它鼠锈。
淺如:
經(jīng)驗分享:CSS浮動(float,clear)通俗講解 篇幅不長,通俗易懂星著,可以看完這篇文章再回過頭來看本文脚祟。
深如:
CSS float浮動的深入研究、詳解及拓展(一)
CSS float浮動的深入研究强饮、詳解及拓展(二)
從本質(zhì)上講解了 float 的原理由桌。
我就不班門弄斧寫原理了,只說說 float 的幾個要點就行了:
只有左右浮動,沒有上下浮動行您。
元素設(shè)置 float 之后铭乾,它會脫離普通流(和
position: absolute;
一樣),不再占據(jù)原來那層的空間娃循,還會覆蓋下一層的元素炕檩。浮動不會對該元素的上一個兄弟元素有任何影響。
浮動之后捌斧,該元素的下一個兄弟元素會緊貼到該元素之前沒有設(shè)置 float 的元素之后(很好理解笛质,因為該元素脫離普通流了,或者說不在這一層了捞蚂,所以它的下一個元素當然要補上它的位置)妇押。
如果該元素的下一個兄弟元素中有內(nèi)聯(lián)元素(通常是文字),則會圍繞該元素顯示姓迅,形成類似「文字圍繞圖片」的效果敲霍。(可參考CSS float浮動的深入研究、詳解及拓展(一)中的講解)丁存。這個我還是實踐了一下的肩杈,點這個JSfiddle看看吧。
下一個兄弟元素如果也設(shè)置了同一方向的 float解寝,則會緊隨該元素之后顯示扩然。
該元素將變?yōu)閴K級元素,相當于給該元素設(shè)置了
display: block;
(和position: absolute;
一樣)聋伦。
這里還有個東西夫偶,就是廣為人知的——清除浮動。具體的方法五花八門嘉抓,可以看這篇:那些年我們一起清除過的浮動索守,我就不多說了。
寫完本文后抑片,腦子中又出現(xiàn)了一系列問題卵佛,假如 position 和 float 同時設(shè)置會出現(xiàn)什么問題?兼容性如何敞斋?哪個屬性會被覆蓋截汪?還沒來得及實踐,改天以排列組合的方式看看到底是什么效果……如果有人實踐過可以偷偷告訴我_
原文地址:CSS 最核心的幾個概念
本作品采用知識共享 署名-非商業(yè)性使用-禁止演繹 4.0 國際 許可協(xié)議進行許可植捎。