原文網址連接:http://www.geekplux.com/2014/04/25/several_core_concepts_of_css.html
css
本文將講述 CSS 中最核心的幾個概念,包括:盒模型、position、float等。這些是 CSS 的基礎,也是最經常使用的幾個屬性,它們之間看似獨立卻又相輔相成。爲了掌握它們,有必要寫出來探討一下,若有錯誤歡迎指正。html
元素類型web
HTML 的元素能夠分爲兩種:瀏覽器
二者的區別在於如下三點:.net
塊級元素會獨佔一行(即沒法與其餘元素顯示在同一行內,除非你顯式修改元素的 display 屬性),而內聯元素則都會在一行內顯示。ssr
塊級元素能夠設置 width、height 屬性,而內聯元素設置無效。orm
塊級元素的 width 默認爲 100%,而內聯元素則是根據其自身的內容或子元素來決定其寬度。htm
最多見塊級元素應該是 <div> 吧,內聯元素有 <span> <a> <img> 等等,完整的元素列表能夠谷歌一下。
具體來講一下吧,
.example {
width: 100px;
height: 100px;
}
咱們爲 <div> 設置上面的樣式,是有效果的,由於其是塊級元素,而對 <span> 設置上面的樣式是沒用的。要想讓 <span> 也能夠改變寬高,能夠經過設置 display: block; 來達到效果。當 display 的值設爲 block 時,元素將以塊級形式呈現;當 display 值設爲 inline 時,元素將之內聯形式呈現。
若既想讓元素在行內顯示,又能設置寬高,能夠設置:
display: inline-block;
inline-block 在我看來就是讓元素對外呈內聯元素,能夠和其餘元素共處與一行內;對內則讓元素呈塊級元素,可改變其寬高。
HTML 代碼是順序執行的,一份無任何 CSS 樣式的 HTML 代碼最終呈現出的頁面是根據元素出現的順序和類型排列的。塊級元素就從上到下排列,遇到內聯元素則從左到右排列。這種無樣式的狀況下,元素的分佈叫普通流,元素出現的位置應該叫正常位置(這是我瞎起的),同時全部元素會在頁面上佔據一個空間,空間大小由其盒模型決定。
盒模型
頁面上顯示的每一個元素(包括內聯元素)均可以看做一個盒子,即盒模型( box model )。請看 Chrome DevTools 裏的截圖:
能夠顯而易見的看出盒模型由 4 部分組成。從內到外分別是:
content -> padding -> border -> margin
按理來講一個元素的寬度(高度以此類推)應該這樣計算:
總寬度 = margin-left + border-left + padding-left + width + padding-right + border-right + margin-right
可是不一樣瀏覽器(你沒有猜錯,就是那個不同凡響的瀏覽器)對寬度的詮釋不同。符合 W3C 標準的瀏覽器認爲一個元素的寬度只等於其 content 的寬度,其他都要額外算。因而你規定一個元素:
.example {
width: 200px;
padding: 10px;
border: 5px solid #000;
margin: 20px;
}
則他最終的寬度應爲:
寬度 = width(200px) + padding(10px * 2) + border(5px * 2) + margin(20px * 2) = 270px;
而在 IE(低於IE9) 下,最終寬度爲:
寬度 = width(200px) + margin(20px * 2) = 240px;
我我的以爲 IE 的更符合人類思惟,畢竟 padding 叫內邊距,邊框算做額外的寬度也說不下去。W3C 最後爲了解決這個問題,在 CSS3 中加了 box-sizing 這個屬性。當咱們設置 box-sizing: border-box; 時,border 和 padding 就被包含在了寬高以內,和 IE 以前的標準是同樣的。因此,爲了不你同一份 css 在不一樣瀏覽器下表現不一樣,最好加上:
*, *:before, *:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
這裏還有兩種特殊狀況:
它們在頁面上的表現均不佔據空間(脫離普通流,感受像浮在頁面上層同樣,移動它們不影響其餘元素的定位)。這就涉及到另外兩個核心概念 position 和 float。
position
position 這個屬性決定了元素將如何定位。它的值大概有如下五種:
position 值 |
如何定位 |
static |
position的默認值。元素將定位到它的正常位置(上文提到過),其實也就至關於沒有定位。元素在頁面上佔據位置。不能使用 top right bottom left 移動元素位置。 |
relative |
相對定位,相對於元素的正常位置來進行定位。元素在頁面佔據位置。能夠使用 top right bottom left 移動元素位置。 |
absolute |
絕對定位,相對於最近一級的 定位不是 static 的父元素來進行定位。元素在頁面不佔據位置。 能夠使用 top right bottom left 移動元素位置。 |
fixed |
絕對定位,相對於瀏覽器窗口來進行定位。其他和 absolute 同樣,至關於一種特殊的 absolute。 |
inherit |
從父元素繼承 position 屬性的值。 |
具體效果能夠參考w3school的實例:http://www.w3school.com.cn/cssref/pr_class_position.asp,或者本身寫一下就明白了。
每一個網頁均可以當作是由一層一層頁面堆疊起來的,以下圖所示。
position 設置爲 relative 的時候,元素依然在普通流中,位置是正常位置,你能夠經過 left right 等移動元素。會影響其餘元素的位置。
而當一個元素的 position 值爲 absolute 或 fixed 的時候,會發生三件事:
把該元素往 Z 軸方向移了一層,元素脫離了普通流,因此再也不佔據原來那層的空間,還會覆蓋下層的元素。
該元素將變爲塊級元素,至關於給該元素設置了 display: block;(給一個內聯元素,如 <span> ,設置 absolute 以後發現它能夠設置寬高了)。
若是該元素是塊級元素,元素的寬度由原來的 width: 100%(佔據一行),變爲了 auto。
由此觀之,當 position 設置爲 absolute 或 fixed,就不必設置 display 爲 block 了。並且若是你不想覆蓋下層的元素,能夠設置 z-index 值 達到效果。
float
float 顧名思義,就是把元素浮動,它的取值一共有四個:left right none inherit,光看名字就懂了,無需多言。
最初的 float 只是用來實現文字環繞圖片的效果,僅此而已。而如今 float 的應用已不止這個,前輩們也是寫了無數博文來深刻淺出的講解它。
淺如:
經驗分享:CSS浮動(float,clear)通俗講解(http://www.cnblogs.com/iyangyuan/archive/2013/03/27/2983813.html)篇幅不長,通俗易懂,能夠看完這篇文章再回過頭來看本文。
深如:
CSS float浮動的深刻研究、詳解及拓展(一)(http://www.zhangxinxu.com/wordpress/2010/01/css-float%E6%B5%AE%E5%8A%A8%E7%9A%84%E6%B7%B1%E5%85%A5%E7%A0%94%E7%A9%B6%E3%80%81%E8%AF%A6%E8%A7%A3%E5%8F%8A%E6%8B%93%E5%B1%95%E4%B8%80/)
CSS float浮動的深刻研究、詳解及拓展(二)(http://www.zhangxinxu.com/wordpress/2010/01/css-float%E6%B5%AE%E5%8A%A8%E7%9A%84%E6%B7%B1%E5%85%A5%E7%A0%94%E7%A9%B6%E3%80%81%E8%AF%A6%E8%A7%A3%E5%8F%8A%E6%8B%93%E5%B1%95%E4%BA%8C/)
從本質上講解了 float 的原理。
我就不班門弄斧寫原理了,只說說 float 的幾個要點就好了:
只有左右浮動,沒有上下浮動。
元素設置 float 以後,它會脫離普通流(和 position: absolute; 同樣),再也不佔據原來那層的空間,還會覆蓋下一層的元素。
浮動不會對該元素的上一個兄弟元素有任何影響。
浮動以後,該元素的下一個兄弟元素會緊貼到該元素以前沒有設置 float 的元素以後(很好理解,由於該元素脫離普通流了,或者說不在這一層了,因此它的下一個元素固然要補上它的位置)。
若是該元素的下一個兄弟元素中有內聯元素(一般是文字),則會圍繞該元素顯示,造成相似「文字圍繞圖片」的效果。(可參考CSS float浮動的深刻研究、詳解及拓展(一)(http://www.zhangxinxu.com/wordpress/2010/01/css-float%E6%B5%AE%E5%8A%A8%E7%9A%84%E6%B7%B1%E5%85%A5%E7%A0%94%E7%A9%B6%E3%80%81%E8%AF%A6%E8%A7%A3%E5%8F%8A%E6%8B%93%E5%B1%95%E4%B8%80/)中的講解)。這個我仍是實踐了一下的:具體代碼參考:http://jsfiddle.net/GeekPlux/9yAH8/light/
下一個兄弟元素若是也設置了同一方向的 float,則會緊隨該元素以後顯示。
該元素將變爲塊級元素,至關於給該元素設置了 display: block;(和position: absolute; 同樣)。
這裏還有個東西,就是廣爲人知的——清除浮動。具體的方法五花八門,能夠看這篇:那些年咱們一塊兒清除過的浮動(http://www.iyunlu.com/view/css-xhtml/55.html),我就很少說了。
寫完本文後,腦子中又出現了一系列問題,假如 position 和 float 同時設置會出現什麼問題?兼容性如何?哪一個屬性會被覆蓋?還沒來得及實踐,改天以排列組合的方式看看究竟是什麼效果……若是有人實踐過能夠偷偷告訴我^_^