1、CSS 盒模型(Box Model)
所有 HTML 元素都可以看作是盒子,在 CSS 中,“Box Model”這一術語主要是在布局時使用。
CSS 盒模型(Box Model)規定了處理元素內容、邊框、內邊距 和 外邊距 的方式。
CSS 盒模型本質上是一個盒子,封裝周圍的 HTML 元素,它包括:外填充也叫外邊距(margin),邊框(border),內填充也叫內邊距(padding)和實際內容(content)。盒模型允許我們在其它元素和周圍元素邊框之間的空間放置元素。
如下 CSS 盒子模型圖:

盒子模型的最內層是盒子的實際內容(content),顯示文本和圖像。直接包圍內容的是內邊距(padding),清楚內容周圍的區域,內邊距呈現了元素的背景,會受到框中填充的背景顏色影響。內邊距的邊緣是邊框(border),邊框以外是外邊距(margin),外邊距沒有背景顏色,默認是透明的,因此不會遮擋其后的任何元素。背景應用於由內容和內邊距、邊框組成的區域。盒模型就好比一套茶杯,為了避免損壞,每個茶杯的周圍都會被填充一些東西,這些填充就是內邊距,再用盒子把茶杯裝起來,裝茶杯的盒子就是邊框,一套茶杯不可能只有一個,所有的茶杯會用一個精美包裝的大盒子再裝起來,那么每個裝茶杯的小盒子之間的距離就是外邊距。
內邊距、邊框和外邊距都是可選的,默認值是零。但是,許多元素將由瀏覽器樣式表(瀏覽器缺省值)設置外邊距和內邊距。因此可以將元素的 margin 和 padding 設置為零來覆蓋這些瀏覽器樣式。
在 CSS 中,width 和 height 指的是內容區域的寬度和高度。增加內邊距、邊框和外邊距不會影響內容區域的尺寸,但是會增加元素盒子的總尺寸。為了確保在所有瀏覽器中元素的寬度和高度設置正確,有必要了解盒模型是如何工作的。
當指定一個 CSS 元素的寬度和高度屬性時,只是設置了內容區域的寬度和高度,完全大小的元素,還必須添加內邊距,邊框和外邊距。如下設置盒子的樣式:
1 #box{ 2 width:200px; 3 height:100px; 4 padding:20px; 5 border:10px solid blue; 6 margin:30px; 7 }
上面例子中,ID 為 box 的寬為 200 像素,高為 100 像素,內邊距為 20 像素,邊框為 10 像素,外邊距是 30 像素,下圖是在 Firefox 中計算出的布局樣式:

那么該元素的總寬度實際為:30+10+20+200+20+10+30= 320px
實際高度為:30+10+20+100+20+10+30= 220px
最終元素的總寬度計算公式是:總元素的寬度=內容寬度+左外邊距+右外邊距+左邊框+右邊框+左內邊距+右內邊距。
元素的總高度最終計算公式是:總元素的高度=內容高度+頂外邊距+底外邊距+頂邊框+底邊框+頂內邊距+底內邊距。
根據 W3C 的規范,元素內容占據的空間是由 width 屬性設置的,而內容周圍的 padding 和 border 值是另外計算的。內邊距、邊框和外邊距可以應用於一個元素的所有邊,也可以應用於單獨的邊。外邊距可以是負值,而且在很多情況下都要使用負值的外邊距,內邊距不可以是負值。
margin 屬性的值設為負值即負邊距,在 CSS 布局中是一個很有用的技巧。當 margin-top 、 margin-left 為負值的時候,會把元素上移、左移,同時文檔流中的位置也發生相應變化,這點與 position:relative 的元素設置 top、left 后元素還占據原來位置不同。當 margin-bottom 、 margin-right 設為負值的時候,元素本身沒有位置變化,后面的元素會下移、右移。
當元素被設置為絕對定位時,其 top、right、bottom、left 值是指元素自身的邊界到最近的已定位祖先元素的距離,這個元素自身的邊界指的就是 margin 定義的邊界,所以,如果 margin 為正的時候,那它的邊界是向外擴的,即下移/右移,如果 margin 為負的時候,則它的邊界是向內收的,即上移/左移,利用這點,就有了經典的利用絕對定位來居中的方法:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>垂直居中</title> 6 <style> 7 *{padding;margin:0;} 8 #box{ 9 width:200px; 10 height:200px; 11 margin:10px auto; 12 border:1px solid blue; 13 position:relative; 14 } 15 #box .content{ 16 width:100px; 17 height:100px; 18 background:green; 19 position:absolute; 20 top:50%; 21 left:50%; 22 margin-top:-50px; 23 margin-left:-50px; 24 } 25 </style> 26 </head> 27 <body> 28 <div id="box">盒子 29 <div class="content">內容</div> 30 </div> 31 </body> 32 </html>
把元素設置為絕對定位,然后設置 top 和 left 為 50%,這時候元素的上邊界、左邊界就到了父元素的 50% 處,再對元素設置其自身寬度和高度一半的負邊距,使元素中心移動到父元素中心,實現居中對齊。
負邊距對於浮動元素的影響和上面的情況一樣,不過有其特殊性,如下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>負邊距對浮動元素的影響</title> 6 <style> 7 *{padding;margin:0;} 8 #box{ 9 width:280px; 10 border:1px solid black; 11 overflow:hidden; 12 } 13 #box .float{ 14 width:100px; 15 height:100px; 16 float:left; 17 } 18 #box .float:nth-child(1){ 19 background:red; 20 } 21 #box .float:nth-child(2){ 22 background:yellow; 23 } 24 #box .float:nth-child(3){ 25 background:blue; 26 } 27 </style> 28 </head> 29 <body> 30 <div id="box"> 31 <div class="float">1</div> 32 <div class="float">2</div> 33 <div class="float">3</div> 34 </div> 35 </body> 36 </html>
上面代碼中,在一個寬度為 280px 的 div 的容器中向左浮動3個子 div 元素,寬度都為 100px ,由於一行放不下,最后一個會被移動到下一行顯示,如果給第三個元素添加 -20px 的外邊距,這時候第三個元素就移上去了,並且覆蓋了第二個元素 20px ,經典的多列布局正是利用此原理。
1 #box .float:nth-child(3){ 2 background:blue; 3 margin-left:-20px; 4 }
實例:兩列布局
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>兩列布局</title> 6 <style> 7 *{padding;margin:0;font:bold 18px "微軟雅黑";} 8 #box{ 9 width:500px; 10 border:1px solid black; 11 margin:10px auto; 12 overflow:hidden; 13 } 14 #box .wrap{ 15 width:100%; 16 float:left; 17 } 18 #box .wrap .content{ 19 height:200px; 20 margin-right:100px; 21 background:pink; 22 } 23 #box .right{ 24 width:100px; 25 height:200px; 26 background:lightgreen; 27 float:left; 28 margin-left:-100px; 29 } 30 </style> 31 </head> 32 <body> 33 <div id="box"> 34 <div class="wrap"> 35 <div class="content"> 36 1左列內容 2左列內容 3左列內容 4左列內容 5左列內容 6左列內容 7左列內容 8左列內容 9左列內容 37 </div> 38 </div> 39 <div class="right">右列內容</div> 40 </div> 41 </body> 42 </html>
上面的代碼很好理解,為 content 元素定義父元素,設置左浮動,寬度為 100%,再為 content 元素設置右邊距,值等於 right 元素的寬度,最后給 right 元素設置左浮動,再設置其寬度的負邊距為 content 元素設置右邊距,即自身寬度。
本來 right 元素應該在第二行顯示,但是左浮動使它到了第一行的最右邊,覆蓋了 wrap 元素的一部分,但是 content 元素有 right 元素寬度的右邊距,所以覆蓋區域沒有內容,這樣就實現了兩列布局。注意:如果不給 content 元素設置 right 元素寬度的右邊距,那么 content 元素的內容則會被覆蓋掉。其它此類更復雜的布局原理與其類似。
2、CSS 邊框
CSS border 屬性可以為元素指定邊框的寬度、樣式和顏色。元素的邊框是圍繞元素內容和內邊距的一條或多條線。
在 CSS 規范中指出,邊框是繪制在“元素的背景之上”。這很重要,因為有些邊框是“間斷的“,如:點線邊框或虛線框,元素的背景應當出現在邊框的可見部分之間。CSS2 指出背景只延伸到內邊距,而不是邊框。在 CSS2.1 中定義:元素的背景是內容、內邊距和邊框區的背景。
(1)、邊框樣式(border-style)
border-style 屬性用來定義邊框的樣式。邊框樣式屬性指定要顯示什么樣的邊界,樣式是邊框最重要的一個屬性,如果沒有樣式,將根本沒有邊框。
CSS 的 border-style 屬性定義了 10 個不同的非 inherit(繼承) 樣式,包括 none 和 hidden,該屬性無繼承。如下:
①、默認值為 none:無邊框。border-color 將被忽略,border-width 計算值為0,除非邊框輪廓為圖像,即 border-image。
②、hidden:隱藏邊框。
③、dotted:點狀框。
④、dashed: 虛線框。
⑤、solid: 實線框。
⑥、double: 雙線框。 兩條單線的寬度和 border-width 值相同。
⑦、groove: 3D 凹槽框。效果取決於邊界的顏色值。
⑧、ridge: 3D 凸槽框。效果取決於邊界的顏色值。
⑨、inset:3D 嵌入(凹)邊框。效果取決於邊界的顏色值。
⑩、outset:3D 突出(凸)邊框。效果取決於邊界的顏色值。
border-style 屬性可以定義多種樣式,即為一個邊框定義多個樣式,如下:
1 <head> 2 <style> 3 #box{ 4 width:500px; 5 height:300px; 6 color:blue; 7 background:lightgreen; 8 border-style:solid dotted dashed double; 9 } 10 </style> 11 </head> 12 <body> 13 <div id="box"> 14 內容 15 </div> 16 </body>
上面例子中,為 div 元素的邊框樣式分別為:頂邊框為實線框,右邊框為點狀框,底邊框為虛線框,左邊框為雙線框。
border-style 屬性可以設置一個元素四個邊框的樣式,可以有 1-4 個值:
①、如果提供全部四個參數值,將按上、右、下、左的順序作用於四邊。
②、如果只提供一個,將用於全部的四邊。
③、如果提供兩個,第一個用於上、下,第二個用於左、右。
④、如果提供三個,第一個用於上,第二個用於左、右,第三個用於下。
該屬性屬於復合屬性,也叫簡寫屬性,如果只為元素框的某一個邊框設置樣式,而不是設置所有 4 個邊的邊框樣式,可以使用下面的單邊邊框樣式屬性:
①、border-top-style 設置或檢索對象頂邊框樣式。
②、border-right-style 設置或檢索對象右邊框樣式。
③、border-bottom-style 設置或檢索對象底邊框樣式。
④、border-left-style 設置或檢索對象左邊框樣式。
因此,這兩種方法是等同的:
1 #box1{ 2 border-style:none solid solid solid; 3 } 4 #box2{ 5 border-style:solid; 6 border-top-style:none; 7 }
需要注意:如果使用第二種方法,必須把單邊屬性放在簡寫屬性之后。因為如果把單邊屬性放在 border-style 之前,簡寫屬性的值就會覆蓋單邊值 none。
(2)、邊框寬度(border-width)
通過 border-width 屬性可以為邊框指定寬度。
為邊框指定寬度有兩種方法:
①、可以指定長度值,比如 2px 或 0.1em。
②、使用關鍵字設置,默認值為 medium 定義中等的邊框, thin 定義細邊框,thick 定義粗邊框。
需要注意:CSS 沒有定義 3 個關鍵字的具體寬度,所以一個瀏覽器可能把 thin 、medium 和 thick 分別設置為等於 2px、3px 和 5px,而另一個瀏覽器則分別設置為 1px、2px 和 3px。通常建議為元素指定長度值的邊框。
border-width 屬性可以設置一個元素四個邊框的寬度,可以有 1-4 個值,和 border-style 屬性相同。
①、該屬性有 1個 值時,對應元素的四個邊框。
②、該屬性有 2個 值時,對應元素的頂、底邊框,右、左邊框。
③、該屬性有 3個 值時,對應元素的頂邊框,右、左邊框,底邊框。
④、該元素有 4個 值時,對於元素的頂邊框,右邊框,底邊框,左邊框。
該屬性屬於復合屬性,可以使用單獨的屬性為每個邊框指定寬度:
①、border-top-width 設置或檢索對象頂邊框的寬度。
②、border-right-width 設置或檢索對象右邊框的寬度。
③、border-bottom-width 設置或檢索對象底邊框的寬度。
④、border-left-width 設置或檢索對象左邊框的寬度。
在前面的例子中,如果要顯示某種邊框,就必須設置邊框樣式,比如 solid 或 dashed。如果把 border-style 設置為 none,如下:
1 <head> 2 <style> 3 #box1{ 4 border-style:none; 5 border-width:10px; 6 } 7 #box2{ 8 border-style:solid; 9 border-width:10px; 10 } 11 </style> 12 </head> 13 <body> 14 <div id="box1"> 15 內容 內容 16 </div> 17 <div id="box2"> 18 內容 19 </div> 20 </body>
通過上面的例子,可以看到,盡管 box1 的邊框的寬度是 10px,但是邊框樣式設置為 none。在這種情況下,不僅邊框的樣式沒有了,其寬度也會變成 0。邊框消失了,這是因為如果邊框樣式為 none,即邊框根本不存在,那么邊框就不可能有寬度,因此邊框寬度自動設置為 0,而不論寬度定義的是多少。這一點非常重要,根據下面規則,所有 h1 元素都不會有任何邊框,更不用說 50 像素寬了:
1 h1{ 2 border-width:50px; 3 }
border-style 屬性的默認值是 none,如果沒有聲明樣式,就相當於 border-style:none。所以,如果要想顯示邊框,就必須聲明一個邊框樣式。
(3)、邊框顏色(border-color)
border-color 屬性用於設置邊框的顏色。可以使用任何顏色類型的值,如指定顏色的名稱,"red"。如指定 RGB 值,"rgb(255,0,0)"。如指定16進制值, "#FF0000"。該屬性的默認值為 "transparent" 指定邊框的顏色為透明。注意: border-color 單獨使用是不起作用的,必須得先使用 border-style 來設置邊框樣式。
border-color 屬性可以設置一個元素四個邊框的顏色,可以有 1-4 個值,和 border-width 屬性相同,即按照 top-right-bottom-left 的順序設置元素的各邊邊框。
該屬性屬於復合屬性,可以使用單獨的屬性為每個邊框指定顏色:
①、border-top-color 設置或檢索對象頂邊框的顏色。
②、border-right-color 設置或檢索對象右邊框的顏色。
③、border-bottom-color 設置或檢索對象底邊框的顏色。
④、border-left-color 設置或檢索對象左邊框的顏色。
默認邊框顏色是元素本身的前景色。如果沒有為邊框設置顏色,它將與元素的文本顏色相同。另一方面,如果元素沒有任何文本,假設它是一個表格,其中只包含圖像,那么該表格的邊框顏色就是其父元素的文本顏色,因為 color 屬性可以繼承,這個父元素很可能是 body、div 或另一個 table。
我們可以為網頁上的文字賦予顏色,這就使用到了 CSS 的前景色,前景色使用 color 屬性,且通常使用在文字上。與前景色相對應的就是 CSS 背景色,背景色不同於前景色,文字顏色可以使用 color 屬性,但是包含文字的 p、div、body 等元素的背景顏色則使用 background-color 屬性,前景色具有繼承性,而背景色則沒有繼承。
綜上所述,前景色影響邊框顏色,如下面的實例,不設置 div 元素的邊框顏色:
1 <head> 2 <style> 3 #box{ 4 width:200px; 5 height:100px; 6 border-style:solid; 7 border-width:5px; 8 background:lightgreen; 9 } 10 </style> 11 </head> 12 <body> 13 <div id="box"> 14 內容 15 </div> 16 </body>
上面的例子,給 div 元素設置了背景色為淺綠色,可以看到,元素的背景區包含前景之下直到邊框外邊界的所有空間,包含內容、內邊距,且延伸到邊框。而前景色則影響到了邊框顏色,例子中沒有設置邊框顏色,但是前景色默認是黑色,因此邊框也顯示為黑色,如果給文本定義前景色,那么邊框就顯示為元素的前景色:
1 #box{ 2 width:200px; 3 height:100px; 4 color:red; 5 border-style:solid; 6 border-width:5px; 7 background:lightgreen; 8 }
上面的例子,給 div 元素設置了前景色為紅色,可以看到,邊框也顯示為紅色。‘
透明邊框:
如果邊框沒有樣式,就沒有寬度,不過可以創建一個不可見的邊框。即使用 border-color 屬性的默認值 transparent 指定邊框的顏色為透明,從而可以創建有寬度的不可見邊框,如下:
1 <head> 2 <style> 3 a:link, a:visited{ 4 border-style:solid; 5 border-width:5px; 6 border-color:transparent; 7 } 8 a:hover{ 9 border-color:gray; 10 } 11 </style> 12 </head> 13 <body> 14 <a href="#">AAA</a> 15 <a href="#">BBB</a> 16 <a href="#">CCC</a> 17 </body>
從某種意義上來說,利用 transparent,使用邊框就像是額外的內邊距一樣,此外還有一個好處,就是能在需要的時候使其可見。這種透明邊框相當於內邊距,因為元素的背景會延伸到邊框區域,如果給 a 元素再添加一個背景屬性,就能更形象的展示這種效果。
(4)、邊框屬性簡寫屬性
border 屬性屬於復合屬性,使用該屬性可以把邊框屬性設置在一個聲明中。比如 border:1px solid red;
當使用簡寫屬性時,屬性值的順序依次為:
border-width --> border-style --> border-color
如果上述值缺少一個也沒有關系,例如 border:solid red,也是允許的。
還可以使用單獨的復合屬性為每個邊框設置特性:
①、border-top 設置對象頂邊框的特性。
②、border-right 設置對象右邊框的特性。
③、border-bottom 設置對象底邊框的特性。
④、border-left 設置對象左邊框的特性。
3、CSS 輪廓
輪廓(outline)是繪制於元素周圍的一條線,位於邊框邊緣的外圍,可起到突出元素的作用。
CSS outline 屬性規定元素輪廓的樣式,顏色和寬度。該屬性和 border 屬性一樣,同為復合屬性,不同的是 border 屬性作用於內容和內邊距外圍,而 outline 屬性作用於 border 屬性外圍。輪廓也可以叫做外邊框。
下面的實例,在 div 元素的外圍繪制一條邊框,再給邊框繪制一條輪廓:
1 <head> 2 <style> 3 #box{ 4 border:2px solid red; 5 outline:4px dotted green; 6 } 7 </style> 8 </head> 9 <body> 10 <div id="box"> 11 內容 12 </div> 13 </body>
也可以使用單獨的屬性為邊框設置特性:
①、outline-width 設置或檢索對象外的線條輪廓的寬度。
②、outline-style 設置或檢索對象外的線條輪廓的樣式。
③、outline-color 設置或檢索對象外的線條輪廓的顏色。
4、CSS 內邊距
元素的內邊距在邊框和內容區之間,控制該區域最簡單的屬性是 padding 屬性。
CSS padding 屬性定義元素邊框與元素內容之間的空間,即內邊距,該屬性接受任何類型的長度單位或百分比值,但不允許使用負值。百分數值是相對於其父元素的 width 計算的,這一點與外邊距一樣。所以,如果父元素的 width 改變,它們也會改變。如果上下內邊距與左右內邊距一致,即上下內邊距的百分數會相對於父元素寬度設置,而不是相對於高度。
內邊距也叫做填充,當元素的 padding 被清除時,所“釋放”的區域將會受到元素背景顏色的填充。
(1)、單邊內邊距
padding 屬性屬於復合屬性,可以使用單獨的屬性設置元素的內邊距:
①、padding-top 設置元素的頂內邊距。
②、padding-right 設置元素的右內邊距。
③、padding-bottom 設置元素的底內邊距。
④、padding-left 設置元素的左內邊距。
(2)、內邊距屬性簡寫
padding 屬性允許在一個聲明中設置元素所有的內邊距屬性,可以有 1-4 個值。
①、如果提供全部四個參數值,將按上、右、下、左的順序作用於四邊。
②、如果只提供一個,將用於全部的四邊。
③、如果提供兩個,第一個用於上、下,第二個用於左、右。
④、如果提供三個,第一個用於上,第二個用於左、右,第三個用於下。
這個簡寫屬性設置元素所有內邊距的寬度,或者設置各邊上內邊距的寬度。行內非替換元素上設置的內邊距不會影響行高計算,因此,如果一個元素既有內邊距又有背景,元素的背景會延伸穿過內邊距,從視覺上看可能會延伸到其他行,有可能還會與其他內容重疊。
5、CSS 外邊距
圍繞在元素邊框的空白區域是外邊距,設置外邊距會在元素外創建額外的“空白”。
CSS margin 屬性設置元素周圍的空間,即外邊距,該屬性屬性接受任何類型的長度單位、百分比值,甚至是負值。百分數是相對於父元素的 width 計算的,負值則重疊內容。
外邊距清除周圍的元素邊框外的區域,margin 沒有背景顏色,是完全透明的。
margin 屬性的值可以是 auto 瀏覽器計算外邊距,這樣做的結果會依賴於瀏覽器,更常見的做法是為外邊距設置長度值。但是設置為 auto 也有一個好處,那就是可以在頁面上居中一個元素。下面的例子,將 div 元素的上下外邊距設置為 0,左右外邊距設置為 auto,就可以實現該元素在頁面上居中顯示。
1 <head> 2 <style> 3 *{padding:0;margin:0;} 4 #box{ 5 width:400px; 6 height:200px; 7 background:green; 8 margin:0 auto; 9 } 10 </style> 11 </head> 12 <body> 13 <div id="box"> 14 內容 15 </div> 16 </body>
margin 屬性的默認值是 0,所以如果沒有為 margin 聲明一個值,就不會出現外邊距。但是,在實際中,瀏覽器對許多元素提供了預定的樣式,外邊距也不例外。例如,在瀏覽器中,外邊距會在每個段落元素的前邊和后邊生成一個“空行”。因此,如果沒有為 p 元素聲明外邊距,瀏覽器會自己應用一個外邊距。當然,如果特別作了聲明,就會覆蓋默認樣式。
(1)、單邊外邊距
margin 屬性屬於復合屬性,可以使用單獨的屬性設置元素的外邊距:
①、margin-top 設置元素的頂外邊距。
②、margin-right 設置元素的右外邊距。
③、margin-bottom 設置元素的底外邊距。
④、margin-left 設置元素的左外邊距。
(2)、外邊距屬性簡寫
margin 屬性允許在一個聲明中設置元素所有的外邊距屬性,可以有 1-4 個值。
①、如果提供全部四個參數值,將按上、右、下、左的順序作用於四邊。
②、如果只提供一個,將用於全部的四邊。
③、如果提供兩個,第一個用於上、下,第二個用於左、右。
④、如果提供三個,第一個用於上,第二個用於左、右,第三個用於下。
這個簡寫屬性設置一個元素所有外邊距的寬度,或者設置各邊上外邊距的寬度。塊級元素的垂直相鄰外邊距會重疊,而行內元素實際上不占上下外邊距,行內元素的的左右外邊距不會重疊。同樣地,浮動元素的外邊距也不會重疊。允許指定負的外邊距值,不過需要小心使用。
(3)、外邊距重疊
外邊距重疊,也叫外邊距合並,指的是當兩個或多個垂直外邊距相遇時,它們將形成一個外邊距,重疊后的外邊距的高度等於兩個發生重疊的外邊距的高度中的較大者。如果出現負邊距,則都取絕對值,然后用正值減去最大值。如果都為負邊距,則都取絕對值,然后用零減去最大值。
外邊距合並疊加是不難理解,但是,在實踐中對網頁進行布局時,它會造成許多混淆。
當一個元素出現在另一個元素上面時,第一個元素的下外邊距與第二個元素的上外邊距會發生重疊。如下:
1 <head> 2 <style> 3 *{padding:0;margin:0;} 4 #box1{ 5 width:100px; 6 height:100px; 7 background:red; 8 margin-top:20px; 9 margin-bottom:20px; 10 } 11 #box2{ 12 width:100px; 13 height:100px; 14 background:blue; 15 margin-top:30px; 16 } 17 </style> 18 </head> 19 <body> 20 <div id="box1"> 21 1 22 </div> 23 <div id="box2"> 24 2 25 </div> 26 </body>
上面的例子,box1 設置了底外邊距為 20px,box2 設置了頂外邊距為 30px,在 Firefox 中打開上面的文檔,鼠標分別移動到 box1 和 box2 元素上,可以看到,這兩個元素的外邊距是 30px,而不是 50px(20px+30px)。
發生重疊的條件是子元素的上外邊距或下外邊距與父元素的上邊界或下邊界之間不能出現 padding 或 border。當一個元素包含在另一個元素中時,假設沒有內邊距或邊框把外邊距分隔開,它們的上 和/或 下外邊距也會發生重疊。如下:
1 <head> 2 <style> 3 *{padding:0;margin:0;} 4 #box1{ 5 width:200px; 6 height:200px; 7 background:red; 8 margin-top:20px; 9 } 10 #box2{ 11 width:50px; 12 height:50px; 13 background:blue; 14 margin-top:30px; 15 } 16 </style> 17 </head> 18 <body> 19 <div id="box1"> 20 <div id="box2"> 21 </div> 22 </div> 23 </body>
如果不設置 div 的內邊距和邊框,那么內部 div 的上外邊距將與外部 div 的上外邊距疊加,此時2個 div 距離頁面頂部的距離為 30px。
甚至外邊距可以與自身發生重疊,假設有一個空元素,它有外邊距,但是沒有邊框或填充。在這種情況下,上外邊距與下外邊距就碰到了一起,它們就會發生重疊。如果這個外邊距遇到另一個元素的外邊距,它還會發生重疊。這就是一系列的段落元素占用空間非常小的原因,因為它們的所有外邊距都重疊在一起,形成了一個小的外邊距。
外邊距的重疊只產生在普通流文檔的上下外邊距之間,這個看起來有點奇怪的規則,但是實際上,它是有意義的。假設上下排列一系列規則的塊級元素時,比如段落,第一個段落上面的空間等於段落的上外邊距。如果沒有外邊距重疊,后續所有段落之間的外邊距都將是相鄰上外邊距和下外邊距的和。這意味着段落之間的空間是頁面頂部的兩倍,因為塊元素之間存在外邊距重疊,段落之間就不會產生雙倍的距離,段落之間的上外邊距和下外邊距就合並在一起,這樣各處的距離就一致了。
注意:只有兩個或多個普通文檔流中塊元素的垂直外邊距才會發生外邊距重疊。行內元素、浮動元素或絕對定位之間的外邊距不會合並,且水平邊距永遠不會重疊,根元素的垂直邊距也不會被重疊。
合並操作是以 margin、padding、border 的值為基礎的,即在瀏覽器解析所有這些值之后,合並后的 margin 計算將覆蓋已使用的不同 margin 的值。因此,簡單為元素添加 padding 或者 border 就可以不使邊距重疊。給內層元素可以設置透明邊框 border:1px solid transprent,或者給內層元素設置內邊距 padding:1px。
6、CSS 尺寸和長度單位
(1)、尺寸
CSS 尺寸屬性可以控制元素的高度和寬度。同樣,它也可以增加行間距。CSS 尺寸屬性如下:
| 屬性 | 說明 |
| width | 設置元素的寬度 |
| height | 設置元素的高度 |
| line-height | 設置行高 |
| max-width | 設置元素的最大寬度 |
| max-height | 設置元素的最大高度 |
| min-width | 設置元素的最小寬度 |
| max-height | 設置元素的最小高度 |
(2)、長度單位
在寫 CSS 時最常用到的單位長度就是 px(像素),也會使用 em 、%(相對父元素的大小) 單位等等,其實 CSS 中的長度單位有8個:px,em,ex,pt,pc,in,mm,cm
①、相對長度單位
相對長度單位是網頁中的基本單位,既然是相對,那就表明了其長度單位會隨着他的參考值的變化而變化,不是固定的。因為相對單位沒有一個可觀的測量,相反,他們的實際大小是通過父元素的尺寸來確定的,這以為着他們的大小可以通過相關元素的大小來改變。屬於相對長度單位的有3個:px,em,ex
px:像素(Pixel),相對於設備的長度單位,像素是相對於顯示器屏幕分辨率而言的,是屏幕上顯示數據的最基本的點。px 是一個點,它不是自然界的長度單位,因為並不能精確描述一個“點”到底有多長多大,所以點可以很小,也可以很大,相對於設備來說,如果點很小,那畫面就清晰,就可以稱它為“分辨率高”,反之,就是“分辨率低”。因此,“點”的大小是會“變”的,被稱為“相對長度”。
在 Web 上,網頁布局時常用像素為單位,像素是典型的度量單位,很多其他長度單位直接映射成像素,最終,他們被按照像素處理。
em:相對於當前對象內文本的字體尺寸,如果當前行內文本的字體尺寸未被人為設置,則相對於瀏覽器的默認字體尺寸。
在沒有任何 CSS 規則的前提下,1em 的長度是:
100% = 1em = 1rem = 16px = 12pt = 1pc = 0.17in = 4.2mm = 0.42cm
如果有任何 CSS 規則改變了字體大小,不管在文檔的什么位置,1em 的長度會變成相對於新的 font-size 的大小。
任意瀏覽器的默認字體大小都是 16px,因此 1em = 16px,那么 10px = 0.625em = 62.5%,12px = 0.75em = 75%,顯然這樣的話,如 1.2em則=19.2px,像素的最小單位是點,平時在設置時也不可能用 19.2px 表示,使用 px 時數值不帶小數位。為了簡化 font-size 的換算,可以在 CSS 中的 body 選擇器中聲明 font-size:62.5%,這就使 em 值變為 16px * 62.5%=10px, 即 1em = 10px,那么 12px = 1.2em, 也就是說只需要將原來的 px 數值除以 10,再換上 em 作為單位就好了。也可以自定義設置字體大小,不過這樣設置更簡單,也准確多了,具體需要根據實際的開發去定義。還可以設置為 100%,需要注意在寫 CSS 時如果采用 em 作單位,要避免字體大小的重復聲明,即重復運算。如下:
em 並不是一個固定的值,它會繼承父級元素的字體大小,當設置了 font-size 屬性后,它會逐級向上相乘,所以如果一個設置了 font-size:1.2em 的元素在另一個設置了 font-size:1.2em 的元素里,則結果是 1.2 * 1.2= 1.44,而這個元素又在另一個設置了 font-size:1.2em 的元素里,那么最后計算的結果是 1.2 * 1.2 * 1.2。這意味着即使一個元素設置為 10em,這個元素也不會在他出現的每個地方都是 10em。如果 font-size 變化了,它可能會寬點,也可能會窄點。 比如說在 #content 中聲明了字體大小為 1.2em,那么在聲明 p 的字體大小時就只能是 1em,而不是 1.2em, 因為此 em 非彼 em,它因繼承 #content 的字體大小而變為了 1em=12px。
ex:相對於字符“x”的高度。為小寫字母“x”的高度,通常為字體尺寸的一半。如果當前對行內文本的字體尺寸未被人為設置,則相對於瀏覽器的默認字體尺寸。和 em 不同,當改變 font-family 時 em 不會改變,而 ex 單位會變化,因為一個單位的值和該字體是特殊的約束關系。
②、絕對長度單位
絕對單位是固定的,是自然界標准的長度單位,也稱為“絕對長度”。他們一旦被聲明,將不能通過改變其他元素的字體大小來改變他的大小。屬於絕對長度單位的有5個:pt,pc,in,mm,cm
pt:Point,翻譯為點,但其實應該叫磅,pt 是一個物理度量單位,1pt = 1/72英寸,在 CSS 之外 pt 是最常用的尺寸類型,常被用在印刷排版中,他在語言中也很常見,比如在電腦上 word 字體的字號就使用這個單位,默認為宋體五號字,即10.5pt,10.5pt = 14px = 0.875em = 87.5%,而小五號字為 9pt,9pt = 12px = 0.75em = 75%,在瀏覽器中默認字體為16px,字號則為笑四,1em = 16px = 12pt = 100%。
pc:派卡(Pica),相當於我國新四號鉛字的尺寸。pc 和 pt 一樣,只不過 1pc = 12pt。
in:英寸(Inch),英寸是一個物理度量單位,但是在 CSS 領域,英寸只不過被直接映射成像素罷了。
1in = 96px = 72pt = 6pc = 2.54cm = 25.4mm
mm:毫米(Millimeter),毫米是個小數量級的物理度量單位,1mm = 0.1cm = 3.78px。
cm:厘米(Centimeter),常用的物理度量單位,也會被映射成像素,1cm = 37.8px。
(3)、CSS3 長度單位
在 CSS3 中引入了一些新的相對長度單位:ch、rem、vw、vh、vmin、vmax
ch:相對長度單位,ch 的含義和 ex 的 x-height 相似,只不過 ch 是基於字符“0”的寬度而不是基於字符“x”高度的,當font-family 改變的時候 ch 也會隨着改變。
rem:(root element,html),rem 和 em 一樣也是一個相對單位,但是和 em 不同的是 rem 總是相對於根元素(html)的 font-size,而不像 em 的計算是基於父級的,且 font-size 具有繼承性,因此嵌套層數越深字體越大。所以使用 rem 這種相對單位更簡單,再也不用擔心父級元素的 font-size 了,因為它始終是基於根元素的。rem 單位不僅可以應用在字體上,還可以實現到 CSS 網格系統中。使用 rem 也可以簡化 font-size 的換算,如下:
1 html{ 2 font-size:62.5%; /* 10÷16=62.5% */ 3 } 4 body{ 5 font-size:14px; 6 font-size:1.4rem; /* 14÷10=1.4 */ 7 } 8 p{ 9 font-size:12px; 10 font-size:1.2rem; 11 }
其實不用太糾結到底是默認的 font-size:100%,還是設置為 font-size:62.5%,如果引入了 CSS 預處理工具那么自然可以使用默認值,但是由於其他原因使用 font-size:62.5% 也無可厚非,完全可以在 body 中重置為需要的 font-size。
在網站建設中,一般中文的字體大小是 12px 和 14px,這基本已經成了大多數網站字體的標准大小,而 16px 為中等字體,18px 為較大字體,12px 則為偏小字體。隨着顯示器分辨率不斷提高,12px 的文字在大於 1440*900 的顯示器中看起來會顯得比較小,不宜閱讀,所以現在網頁設計里面用 12px 的已經比較少了,特別是文章正文部分,普遍都會用 14px。一般來說設置為宋體,也可以設置為微軟雅黑。但是對於大於 14px 的文字,特別是大於 16px 的文字,宋體就顯得比較難看了,所以設置為黑體或者微軟雅黑,看起來會舒服一些。
vw:(viewpointWidth),可視區寬度單位,1vw等於視口寬度的1%。vw 單位跟百分比很相似,不同的是 vw 的值對所有的元素都一樣,與父元素的寬度無關。有點像 rem 單位那樣總是相對於根元素。
vh:(viewpointHeight),可視區高度單位,1vh等於視口高度的1%。與 vw 單位一樣,不同的是 vh 是相對於可視區的高度。
vmin:1%的視口的小尺寸,值是當前 vw 和 vh 中較小的值,在標准尺寸類型的使用實例中,和由自己確定屏幕大小的vw、vh單位相比,vmin是一個更有用的度量標准。
vmax:1%的視口的大尺寸,值是 vw 和 vh 中的較大的值。
顯然 vw、vh、vmin、vmax 是針對移動設備的單位,如果視口大小變化了,這三個值也會跟着相應的變化。在進行響應式布局時,常常會使用百分比來布局,然而 CSS 的百分比不總是解決每個問題的最佳方案,CSS 的寬度相對於離它最近的父元素的寬度。 那么使用 vw 和 vh 單位,是基於視口的寬高而不是父元素的寬高, 使用 vh 和 vw 就可以保證元素的寬高適應不同設備。vw 和 vh 對應於 viewport 的 width 和 height,而 vmin 和 vmax 分別對應於 width、height 中的最小值和最大值,假如瀏覽器的寬/高被設置為1000px/600px,那么:
1vmin = 600 * 1/%;
1vmax = 1000 * 1/%;
(4)、%
以百分比為單位的長度值是基於具有相同屬性的父元素的長度值。假如一個元素呈現的寬度是 600px,子元素的寬度設置為 50%,那么子元素呈現的寬度為 300px。百分比不是一個專門的長度單位,但是百分比和長度關系很大,可以相互換算。
7、CSS Display(顯示) 和 Visibility(可見性)
display 屬性設置一個元素應如何顯示,visibility 屬性規定一個元素是否可見。
(1)、隱藏元素:display:none 或 visibility:hidden
隱藏一個元素可以通過把 display 屬性設置為 "none",或把 visibility 屬性設置為 "hidden"。但是請注意,這兩種方法會產生不同的結果。
visibility:hidden 可以隱藏某個元素,但隱藏的元素仍需占用與未隱藏之前一樣的空間。也就是說,該元素雖然被隱藏了,但仍然會影響布局。
該屬性的默認值是 visible 元素是可見的。值為 hidden 則元素是不可見的。即使不可見的元素也會占據頁面上的空間。建議使用 display 屬性來創建不占據頁面空間的不可見元素。值為 collapse 時,當在表格元素中使用時,此值可刪除一行或一列,但是它不會影響表格的布局。被行或列占據的空間會留給其他內容使用。如果此值被用在其他的元素上,會呈現為 "hidden"。
display:none 可以隱藏某個元素,且隱藏的元素不會占用任何空間。也就是說,該元素不但被隱藏了,而且該元素原本占用的空間也會從頁面布局中消失。
該屬性的默認值為 inline 此元素會被顯示為內聯元素,元素前后沒有換行符。值為 none 此元素不會被顯示。值為 block 此元素將顯示為塊級元素,此元素前后會帶有換行符。值為 inline-block 表示行內塊元素。該屬性也有多個值可用於表格設置。
(2)、CSS Display - 塊和內聯元素
大多數 HTML 元素被定義為塊級元素或內聯元素:
塊級元素在瀏覽器顯示時,通常會以新行來開始(和結束),塊狀元素排斥其他元素與其位於同一行,可以設定元素的寬和高以及內外邊距,塊級元素一般是其他元素的容器,可以容納內聯元素和其他塊元素。常見的塊級元素有: <h1> - <h6>, <div>,<p>, <pre>,<hr>,<ul>, <ol>,<dl>,<from>,<table>,<menu>。
內聯元素在顯示時通常不會以新行開始,不可以設置寬和高,但可以設置與其他內聯元素位於同一行,高度由元素內部的文字大小決定,寬度由內容的長度決定,內聯元素一般不能包含塊級元素,內聯元素只能容納文本或者其他內聯元素。常見的內聯元素有:<a>, <span>,<img>,<br>,<input>,<textarea>,<strong>,<em>,<mark>,<i>,<small>。
塊元素是一個元素,占用了全部寬度,在前后都是換行符。而內聯元素只需要必要的寬度,不強制換行。內聯元素的例子:<span>、<a>、<img>。
可以更改內聯元素和塊元素,反之亦然,可以使頁面看起來是以一種特定的方式組合,並仍然遵循 Web 標准。
下面的例子把列表項顯示為內聯元素:
1 <head> 2 <style> 3 li{ 4 display:inline; 5 } 6 </style> 7 </head> 8 <body> 9 <ul> 10 <li><a href="#" target="_blank">HTML</a></li> 11 <li><a href="#" target="_blank">CSS</a></li> 12 <li><a href="#" target="_blank">JavaScript</a></li> 13 <li><a href="#" target="_blank">jQuery</a></li> 14 </ul> 15 </body>
下面的例子把 span 元素作為塊元素:
1 <head> 2 <style> 3 span{ 4 display:block; 5 color:red; 6 } 7 </style> 8 </head> 9 <body> 10 <p>display 屬性<span>可把一個塊元素轉換為內聯元素,</span>反之亦然,<span>也可以把一個內聯元素轉換為塊元素。</span></p> 11 </body>
注意:一個內聯元素設置為 display:block 是不允許有它內部的嵌套塊元素。
8、CSS Position(定位)
CSS position 屬性可以對元素進行定位。
CSS 的定位和浮動屬性,可用於建立列式布局,將布局的一部分與另一部分重疊,即可以將一個元素放在另一個元素后面,並指定一個元素的內容太大時,應該發生什么。元素可以使用頂部,底部,左側和右側屬性進行定位。但是,這些屬性無法單獨工作,除非是先設定 position 屬性。
定位的基本思想很簡單,它允許你定義元素框(盒子模型)相對於其正常位置應該出現的位置,或者相對於父元素、另一個元素甚至瀏覽器窗口本身的位置。這個功能非常強大,而浮動不完全是定位,不過,它當然也不是正常流布局。
CSS 有三種基本的定位機制:普通流、浮動和絕對定位。
除非專門指定,否則所有框都在普通流中定位,也就是說,普通流中的元素的位置由元素在 HTML 中的位置決定。塊級框從上到下一個接一個地排列,框之間的垂直距離是由框的垂直外邊距計算出來。行內框在一行中水平布置,可以使用水平內邊距、邊框和外邊距調整它們的間距。但是,垂直內邊距、邊框和外邊距不影響行內框的高度。由一行形成的水平框稱為行框(Line Box),行框的高度總是足以容納它包含的所有行內框。不過,設置行高可以增加這個框的高度。
定位有四種不同的方法:靜態定位、固定定位、相對定位和絕對定位。
(1)、靜態定位(static)
HTML 元素的默認值,即沒有定位,元素出現在正常的流中,塊級元素生成一個矩形框,作為文檔流的一部分,行內元素則會創建一個或多個行框,置於其父元素中。靜態定位的元素不會受到 top, bottom, left, right 影響。
(2)、固定定位(fixed)
元素的位置相對於瀏覽器窗口是固定位置。類似於將 position 設置為 absolute,不過其包含塊是視窗本身。固定定位使元素的位置與文檔流無關,因此不占據空間,固定定位的元素和其他元素重疊。
下面的例子,將 div 固定在瀏覽器右下角:
1 <head> 2 <style> 3 #box{ 4 width:150px; 5 height:200px; 6 background:green; 7 position:fixed; 8 right:0; 9 bottom:0; 10 } 11 </style> 12 </head> 13 <body style="height:2000px"> 14 <div id="box">固定在右下角。 15 </div> 16 </body>
(3)、相對定位(relative)
相對定位元素的定位是相對其正常位置,仍處在文檔流中,元素的位置相對於它在普通流中的位置偏移某個距離,元素仍保持其未定位前的形狀,它原本所占的空間仍保留。相對定位元素經常被用來作為絕對定位元素的容器塊。
如果對一個元素設置相對定位,它將出現在它所在的位置上。然后,可以通過設置垂直或水平位置,讓這個元素“相對於”它的起點進行移動。如下:
1 <head> 2 <style> 3 #pos1{ 4 color:blue; 5 } 6 #pos2{ 7 color:red; 8 position:relative; 9 top:-50px; 10 left:60px; 11 } 12 </style> 13 </head> 14 <body> 15 <h1 id="pos1">我是普通流中的大標題。</h1> 16 <h1 id="pos2">我是設置了相對定位的大標題。</h1> 17 <h1>我也是普通流中的大標題。</h1> 18 </body>
注意,在使用相對定位時,無論是否進行移動,元素仍然占據原來的空間。因此,移動元素會導致它和其他元素重疊。
(4)、絕對定位(absolute)
絕對定位的元素的位置相對於最近的已定位父元素,如果元素沒有已定位的父元素,那么它的位置相對於 <html>,絕對定位使元素的位置與文檔流無關,因此不占據空間。這一點與相對定位不同,相對定位實際上被看作普通流定位模型的一部分,因為元素的位置相對於它在普通流中的位置。絕對定位的元素和其他元素也會重疊。
設置為絕對定位的元素框從文檔流完全刪除,並相對於其包含塊定位,包含塊可能是文檔中的另一個元素或者是初始包含塊(<html>)。元素原先在正常文檔流中所占的空間會關閉,就好像該元素原來不存在一樣。元素定位后生成一個塊級框,而不論原來它在正常流中生成何種類型的框。
可以使用上面的例子,觀察絕對定位和相對定位的不同,可以將其頂部屬性設置為0,如果使用負值,會超出瀏覽器窗口:
1 <head> 2 <style> 3 #pos1{ 4 color:blue; 5 } 6 #pos2{ 7 color:red; 8 position:absolute; 9 top:0; 10 left:60px; 11 } 12 </style> 13 </head> 14 <body> 15 <h1 id="pos1">我是普通流中的大標題。</h1> 16 <h1 id="pos2">我是設置了絕對定位的大標題。</h1> 17 <h1>我也是普通流中的大標題。</h1> 18 </body>
(5)、堆疊順序(z-index)
因為元素的定位與文檔流無關,所以它們可以覆蓋頁面上的其它元素。可以通過 z-index 屬性控制這些元素的堆放次序。
z-index 屬性用於指定一個元素的堆疊順序,即哪個元素應該放在前面,或后面。一個元素可以有正數或負數的堆疊順序,默認值為 auto 堆疊順序與父元素相等。擁有更高堆疊順序的元素總是會處於堆疊順序較低的元素前面。 注意: 如果兩個定位元素重疊,沒有指定z-index,最后定位在 HTML 代碼中的元素將被顯示在最前面。該屬性只能用於定位元素,且無繼承。該屬性設置一個定位元素沿 z 軸的位置,z 軸定義為垂直延伸到顯示區的軸。如果為正數,則離用戶更近,為負數則表示離用戶更遠。
1 <head> 2 <style> 3 *{padding:0;margin:0;} 4 #box1{ 5 width:500px; 6 height:100px; 7 background:blue; 8 position:relative; 9 z-index:100; 10 } 11 #box2{ 12 width:800px; 13 height:200px; 14 background:red; 15 position:absolute; 16 top:20px; 17 left:50px; 18 } 19 #box3{ 20 width:1000px; 21 height:300px; 22 background:green; 23 position:absolute; 24 top:40px; 25 left:100px; 26 z-index:-1; 27 } 28 </style> 29 </head> 30 <body> 31 <div id="box1">1 32 </div> 33 <div id="box2">2 34 </div> 35 <div id="box3">3 36 </div> 37 </body>
上面的例子,默認的堆疊順序是 box1 在最底層,下來是 box2,box3 顯示在最上層。給 box3 設置為 z-index:-1;,那么 box3 會顯示在最底層,下來是 box1,box2 會顯示在最上層。再給 box1 設置 z-index:100;,最終 box1 顯示在最上層,下來是 box2,box3 被顯示在最底層。
(6)、固定層效果
固定層效果是固定定位的應用,這種效果在網站中也很常見,比如在頁面頂部固定導航欄菜單,當頁面滾動時,內容從導航欄菜單下面穿過,或者側邊欄固定在頁面右底部。如下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>固定層效果</title> 6 <style> 7 *{padding:0;margin:0;} 8 body{ 9 background:#EEEEE0; 10 } 11 #header{ 12 width:100%; 13 height:50px; 14 background:#99CC33; 15 position:fixed; 16 top:0; 17 left:0; 18 } 19 #conten{ 20 width:80%; 21 height:1000px; 22 border:1px solid black; 23 margin:0 auto; 24 margin-top:70px; 25 } 26 #conten .main{ 27 width:200px; 28 height:400px; 29 background:yellow; 30 } 31 #sidebar{ 32 width:80px; 33 height:80px; 34 background:green; 35 position:fixed; 36 right:0; 37 bottom:0; 38 } 39 #footer{ 40 width:100%; 41 background:#cdcdc1; 42 text-align:center; 43 margin-top:20px; 44 padding:20px 0; 45 } 46 </style> 47 </head> 48 <body> 49 <div id="header"> 50 <h2>網站頭部</h2> 51 </div> 52 <div id="conten"> 53 <div class="main"> 54 <h2>內容</h2> 55 </div> 56 </div> 57 <div id="sidebar"> 58 <h2>側邊欄</h2> 59 </div> 60 <div id="footer"> 61 <h2>頁腳</h2> 62 </div> 63 </body> 64 </html>
為了提高用戶體驗,增強交互效果,可以配合 JS 對頁面進行控制,就像電商網站的頁面效果,當頁面從商品簡介滾動到商品詳情、用戶評論時,將導航欄菜單固定在頁面頂部,這樣評論數就會從導航欄菜單下穿過,方便用戶使用。
position 三種形式定位的影響因素:屬性的取值、元素的偏移量和元素偏移的參考基准。
absolute 與 fixed 相同點都是完全脫離文檔流,未設置偏移量時都定位在父元素的左上角。元素設置定位后就具備偏移屬性和堆疊屬性,只有元素在設置相對定位,或者絕對定位后,堆疊屬性才有效,它的作用是設置元素所在的 z 軸層級。z-index值越大,元素層級越大。
他們的不同點是設置偏移時,偏移的參考基准,absolute 無已定位祖先元素時,以 <html> 為基准偏移;有已經定位的祖先元素時,以距其最近的已定位元素為基准偏移,通常設置了 relative 的元素常被用來做 absolute 元素的容器塊。fixed 有、無已定位祖先元素,都已瀏覽器可視窗口為基准偏移。
他們還存在表現形式的差異,即滾動條,absolute 的位置會隨滾動條變化,而 fixed 的位置是固定不變的,不會隨滾動條變化,兄弟元素可以從其下穿過。
fixed 的定位形式也屬於絕對對位,但不同於 absolute,fixed 的位置固定不變,未設置偏移量時,有已定位的祖先元素,以祖先元素為基准定位;無已定位祖先元素時,以瀏覽器窗口為基准定位。設置偏移量后,有無已定位祖先元素,均以瀏覽器窗口定位。
9、CSS Float(浮動)
在 CSS 中,通過 float 屬性來實現元素的浮動。浮動會使元素向左或向右移動,直到他的外邊緣碰到包含框或另一個浮動框的邊框為止,其周圍的元素也會重新排列。浮動元素之后的元素將圍繞它,浮動元素之前的元素不會受到影響。由於浮動框不在文檔的普通流中,所以文檔的普通流中的塊框表現得就像浮動框不存在一樣。浮動往往是用於圖像,但它在布局時一樣非常有用。浮動也可以理解為向一邊看齊,即就是向左看齊或者向右看齊,元素是在水平方向浮動,那么意味着元素只能左右移動而不能上下移動。
(1)、浮動
①、創建浮動,可以使文本圍繞圖像。
如果圖像是左浮動,下面的文本流將環繞在它右邊,如果圖像是右浮動,下面的文本流將環繞在它左邊。如下:
1 <head> 2 <style> 3 img{ 4 /* float:left; */ 5 float:right; 6 } 7 </style> 8 </head> 9 <body> 10 <p>浮動元素之后的元素將圍繞它,浮動元素之前的元素不會受到影響。</p> 11 <p>浮動會使元素向左或向右移動,直到它的外邊緣碰到包含框或另一個浮動框的邊框為止,其周圍的元素也會重新排列。浮動元素之后的元素將圍繞它,浮動元素之前的元素不會受到影響。浮動往往是用於圖像,但它在布局時一樣非常有用。浮動也可以理解為向一邊看齊,即就是向左看齊或者向右看齊,元素是在水平方向浮動,那么意味着元素只能左右移動而不能上下移動。 12 13 <img src="images/1.jpg" width="90px" height="90px" alt=""> 14 15 浮動會使元素向左或向右移動,直到它的外邊緣碰到包含框或另一個浮動框的邊框為止,其周圍的元素也會重新排列。浮動元素之后的元素將圍繞它,浮動元素之前的元素不會受到影響。浮動往往是用於圖像,但它在布局時一樣非常有用。浮動也可以理解為向一邊看齊,即就是向左看齊或者向右看齊,元素是在水平方向浮動,那么意味着元素只能左右移動而不能上下移動。 16 17 浮動會使元素向左或向右移動,直到它的外邊緣碰到包含框或另一個浮動框的邊框為止,其周圍的元素也會重新排列。浮動元素之后的元素將圍繞它,浮動元素之前的元素不會受到影響。浮動往往是用於圖像,但它在布局時一樣非常有用。浮動也可以理解為向一邊看齊,即就是向左看齊或者向右看齊,元素是在水平方向浮動,那么意味着元素只能左右移動而不能上下移動。 18 19 浮動會使元素向左或向右移動,直到它的外邊緣碰到包含框或另一個浮動框的邊框為止,其周圍的元素也會重新排列。浮動元素之后的元素將圍繞它,浮動元素之前的元素不會受到影響。浮動往往是用於圖像,但它在布局時一樣非常有用。浮動也可以理解為向一邊看齊,即就是向左看齊或者向右看齊,元素是在水平方向浮動,那么意味着元素只能左右移動而不能上下移動。 20 </p> 21 </body>
彼此相鄰的浮動元素,如果有空間的話,它們將彼此相鄰,即在一行顯示,如下:
1 <head> 2 <style> 3 #box{ 4 width:400px; 5 height:350px; 6 border:1px solid black; 7 margin:10px auto; 8 overflow:hidden; 9 } 10 img{ 11 float:left; 12 margin:0 10px 10px 0; 13 } 14 </style> 15 </head> 16 <body> 17 <p>浮動元素之后的元素將圍繞它,浮動元素之前的元素不會受到影響。</p> 18 <div id="box"> 19 <img src="images/1.jpg" width="90px" height="90px" alt=""> 20 <img src="images/1.jpg" width="90px" height="90px" alt=""> 21 <img src="images/1.jpg" width="90px" height="90px" alt=""> 22 <img src="images/1.jpg" width="90px" height="90px" alt=""> 23 <img src="images/1.jpg" width="90px" height="90px" alt=""> 24 <img src="images/1.jpg" width="90px" height="90px" alt=""> 25 <img src="images/1.jpg" width="90px" height="90px" alt=""> 26 <img src="images/1.jpg" width="90px" height="90px" alt=""> 27 <img src="images/1.jpg" width="90px" height="90px" alt=""> 28 <img src="images/1.jpg" width="90px" height="90px" alt=""> 29 <img src="images/1.jpg" width="90px" height="90px" alt=""> 30 <img src="images/1.jpg" width="90px" height="90px" alt=""> 31 <img src="images/1.jpg" width="90px" height="90px" alt=""> 32 <img src="images/1.jpg" width="90px" height="90px" alt=""> 33 <img src="images/1.jpg" width="90px" height="90px" alt=""> 34 <img src="images/1.jpg" width="90px" height="90px" alt=""> 35 </div> 36 </body>
上面的例子,如果不給浮動的圖像設置外邊距,所有的圖像會緊挨在一起顯示,猶如一張圖像。
②、浮動不在文檔普通流中
下面的例子,3個 div 元素在普通流中垂直顯示,當把 box1 向右浮動時,他會脫離文檔流並且向右移動,知道他的右邊緣碰到包含框(<html>)的右邊緣:
1 <head> 2 <style> 3 #box1{ 4 width:200px; 5 height:100px; 6 background:blue; 7 float:right; 8 } 9 #box2{ 10 width:200px; 11 height:100px; 12 background:red; 13 } 14 #box3{ 15 width:200px; 16 height:100px; 17 background:green; 18 } 19 </style> 20 </head> 21 <body> 22 <p>由於浮動框不在文檔的普通流中,所以文檔的普通流中的塊框表現得就像浮動框不存在一樣。</p> 23 <div id="box1">1 24 </div> 25 <div id="box2">2 26 </div> 27 <div id="box3">3 28 </div> 29 </body>
如果把 box1 向左浮動,他會脫離文檔流並且向左移動,直到他的左邊緣碰到包含框的左邊緣。因為它不再處於文檔流中,所以它不占據空間,實際上會覆蓋掉 box2,使 box2 從視圖中消失。為了達到演示效果,可以稍微修改下3個 div 元素的的樣式:
1 #box1{ 2 width:200px; 3 height:100px; 4 background:blue; 5 float:left; 6 } 7 #box2{ 8 width:300px; 9 height:100px; 10 background:red; 11 } 12 #box3{ 13 width:400px; 14 height:100px; 15 background:green; 16 }
如果把所有3個 box 都向左浮動,那么 box1 向左浮動直到碰到包含框,另外兩個 box 向左浮動直到碰到前一個浮動框:
1 #box1{ 2 width:200px; 3 height:100px; 4 background:blue; 5 float:left; 6 } 7 #box2{ 8 width:200px; 9 height:100px; 10 background:red; 11 float:left; 12 } 13 #box3{ 14 width:200px; 15 height:100px; 16 background:green; 17 float:left; 18 }
如果包含框太窄,無法容納水平排列的三個浮動元素,那么其它浮動塊向下移動,直到有足夠的空間。如果浮動元素的高度不同,那么當它們向下移動時可能被其它浮動元素“卡住”,如下:
1 <head> 2 <style> 3 #box{ 4 width:450px; 5 height:300px; 6 border:1px solid black; 7 margin:10px auto; 8 } 9 #box1{ 10 width:200px; 11 height:150px; 12 background:blue; 13 float:left; 14 } 15 #box2{ 16 width:200px; 17 height:100px; 18 background:red; 19 float:left; 20 } 21 #box3{ 22 width:200px; 23 height:100px; 24 background:green; 25 float:left; 26 } 27 </style> 28 </head> 29 <body> 30 <p>如果包含框太窄,無法容納水平排列的三個浮動元素,那么其它浮動塊向下移動,直到有足夠的空間。如果浮動元素的高度不同,那么當它們向下移動時可能被其它浮動元素“卡住”。</p> 31 <div id="box"> 32 <div id="box1">1 33 </div> 34 <div id="box2">2 35 </div> 36 <div id="box3">3 37 </div> 38 <p>浮動會影響處於其后的元素,需要清除浮動的影響。</p> 39 </div> 40 </body>
(2)、清除浮動
元素浮動之后,周圍的元素將重新排列,浮動元素之后的元素會圍繞它,為了避免這種情況,可以使用 clear 屬性。
clear 屬性指定元素兩側不能出現浮動元素。該屬性的默認值是 none 允許浮動元素出現在兩側,還可以是 left、right、both,它表示框的哪些邊不應該挨着浮動框。
大多情況下都會使用 clear:both; 左右兩端均不出現浮動元素。
對於上面例子中的情況,就可以用 clear 屬性給 p 元素設置清除浮動影響:
1 p{ 2 clear:both; 3 }
(3)、overflow
overflow 屬性指定如果內容溢出一個元素的框,會發生什么。在上面彼此相鄰元素的浮動中,給父容器設置了寬高,因為圖像很多,超出了父容器,在代碼中使用了 overflow:hidden; 對溢出的內容進行了隱藏。下面再通過一個例子來看下:
1 <head> 2 <style> 3 #box{ 4 width:200px; 5 height:200px; 6 border:5px solid black; 7 } 8 #box .content{ 9 width:300px; 10 height:400px; 11 background:red; 12 } 13 </style> 14 </head> 15 <body> 16 <div id="box"> 17 <div class="content"> 18 </div> 19 </div> 20 <p>子元素高度超出了父容器的高度,超出的部分就屬於溢出的內容。</p> 21 </body>
為了防止布局被撐開,只需要給父容器設置 overflow:hidden 就可以強制隱藏溢出的內容。在網站開發中,常常會使用到該方法。overflow 屬性的默認值是 visible 內容不會被修剪,會呈現在元素框之外。值為 hidden 時內容會被修剪,並且其余內容是不可見的。值為 scroll 時內容會被修剪,但是瀏覽器會顯示滾動條以便查看其余的內容。值為 auto 時,如果內容被修剪,則瀏覽器會顯示滾動條以便查看其余的內容。
使用了溢出隱藏之后,如果把父容器的高度注釋掉,設置子元素左浮動,會發現父容器的高度自動被子元素的高度撐開了,如果不設置溢出隱藏,則父容器不會被撐開,將上面例子中的代碼稍微改動下:
1 <head> 2 <style> 3 #box{ 4 width:450px; 5 /* height:200px; */ 6 border:5px solid black; 7 overflow:hidden; 8 } 9 #box .content{ 10 float:left; 11 width:200px; 12 height:400px; 13 background:red; 14 margin-right:20px; 15 } 16 </style> 17 </head> 18 <body> 19 <div id="box"> 20 <div class="content"> 21 </div> 22 <div class="content"> 23 </div> 24 </div> 25 <p>子元素高度超出了父容器的高度,超出的部分就屬於溢出的內容。</p> 26 </body>
按照之前的解釋,由於浮動框不在文檔的普通流中,所以文檔普通流中的塊框表現得就像浮動框不存在一樣。浮動也可以理解為向一邊看齊,元素是在水平方向浮動,這就意味着元素只能左右移動而不能上下移動,即就是在一個平面上的浮動,但是上面的例子,浮動並不僅僅是一個平面上的浮動,而是一個立體的浮動,當子元素設置了浮動之后,在顯示器側面,他已經脫離了父容器,也就是說此時的子元素的寬高是多少,對於已經脫離了的父容器來說,是不起作用的。所以使用 overflow:hidden 還可以清除浮動,也就是說,當給父容器設置這個屬性時,其內的子元素等帶浮動屬性的元素在這個立體的浮動已經被清除了。
如果給父容器設置高度,或者釋放之前的高度注釋,那么無論子元素的高度是多少,父容器的高度都是指定的值,並不會被撐開,而當子元素的高度超出父容器的高度時,超出的部分就會被隱藏,該屬性可以保證 div 的高度或寬度不變。該屬性主要用於規定,當一個塊元素容器的內容溢出元素的盒模型邊界時是否對其進行修剪,也就是隱藏,他影響被應用元素的所有內容的修剪,即作為所有子元素的包含塊,但如果后代元素的包含塊是整個視區(通常指瀏覽器內容可視區域,可以理解為 body 元素)或者是該容器(定義了 overflow 的元素)的父級元素時,則不受影響。
10、CSS 對齊(align)
(1)、塊元素水平對齊
在 CSS 中,可以使用多種屬來實現元素水平對齊。
塊元素指的是占據全部可用寬度的元素,並且在其前后都會換行,排斥其他元素與其位於同一行。
①、使用 margin 屬性
塊元素可以把左,右外邊距設置為“auto”,實現水平對齊,也可以叫做中心對齊。
margin 屬性把左和右設置為自動,規定均等的分配可用的外邊距,結果就是元素居中顯示。
1 <head> 2 <style> 3 #box{ 4 width:300px; 5 height:200px; 6 background:blue; 7 margin:auto; 8 } 9 </style> 10 </head> 11 <body> 12 <div id="box"> 13 </div> 14 </body>
注意:如果寬度是 100%,對齊是沒有效果的。
②、使用 position 屬性
使用絕對定位是元素對齊方法之一,可以設置左和右對齊。絕對定位與文檔流無關,所以它們可以覆蓋頁面上的其它元素。
1 <head> 2 <style> 3 #box{ 4 width:300px; 5 height:200px; 6 background:blue; 7 position:absolute; 8 right:0px; 9 } 10 </style> 11 </head> 12 <body> 13 <div id="box"> 14 </div> 15 </body>
③、使用 float 屬性
對齊元素的另一個方法就是使用 float 屬性,可以實現左和右對齊。
1 <head> 2 <style> 3 #box{ 4 width:300px; 5 height:200px; 6 background:blue; 7 float:right; 8 } 9 </style> 10 </head> 11 <body> 12 <div id="box"> 13 </div> 14 </body>
(2)、文本水平對齊
text-align 屬性用於指定元素文本的水平對齊方式。該屬性通過指定行框與哪個點對齊,從而設置塊級元素內文本的水平對齊方式。默認值為 left 把文本排列到左邊,right 把文本排列到右邊,center 把文本排列到中間。
1 <head> 2 <style> 3 h1{ 4 text-align:center; 5 } 6 h2{ 7 text-align:left; 8 } 9 h3{ 10 text-align:right; 11 } 12 </style> 13 </head> 14 <body> 15 <h1>我是大標題。</h1> 16 <h2>我是中標題。</h2> 17 <h3>我是小標題。</h3> 18 </body>
(3)、垂直對齊
vertical-align 屬性可以設置一個元素的垂直對齊方式。該屬性定義行內元素的基線相對於該元素所在行的基線的垂直對齊。允許指定負長度值和百分比值,這會使元素降低而不是升高。在表單元格中,這個屬性會設置單元格框中的單元格內容的對齊方式。
默認值為 baseline 元素放置在父元素的基線上,top 元素的頂端與行中最高元素的頂端對齊,middle 把此元素放置在父元素的中部。bottom 元素的頂端與行中最低的元素的頂端對齊。text-top 元素的頂端與父元素字體的頂端對齊,text-bottom 元素的底端與父元素字體的底端對齊。sup/sub 垂直對齊文本的上標/下標。也可以使用 "line-height" 屬性的百分比值來排列此元素,允許使用負值。
1 <head> 2 <style> 3 img.top{ 4 vertical-align:text-top; 5 } 6 img.mid{ 7 vertical-align:middle; 8 } 9 img.bot{ 10 vertical-align:text-bottom; 11 } 12 </style> 13 </head> 14 <body> 15 <p>元素的頂端<img class="top" src="images/1.jpg" width="90px" height="90px">與父元素字體的頂端對齊。</p> 16 <p>元素與父元素的中間對齊。<img class="mid" src="images/1.jpg" width="90px" height="90px"></p> 17 <p>元素的底端<img class="bot" src="images/1.jpg" width="90px" height="90px">與父元素字體的底端對齊。</p> 18 </body>
11、CSS 圖像透明度
通過 CSS 創建透明圖像是很容易的,CSS3 的 opacity 屬性可以為一個元素設置透明度。
該屬性的值為數值,從 0.0 - 1,值越小,使元素更加透明,0.0 為完全透明,1 則完全不透明。
IE8 及更早版本的瀏覽器則使用 filter 屬性來設置元素的透明,filter:alpha(opacity=value);
filter 屬性的值也為數值,不過是從 0 - 100,較低的值,使得元素更加透明,0 為完全透明,100 則完全透明。
(1)、創建一個透明圖像
創建透明圖像,只需要給圖像標簽設置 opacity 屬性就好了,根據不同的需求,可以設置不同的透明度級別。
1 img{ 2 opacity:0.5; 3 }
(2)、透明圖像懸停效果
懸停效果即鼠標懸停在圖像上時,圖像是完全不透明的,當鼠標移出后,圖像變為透明。該效果可以使用 hover 實現。
1 img{ 2 opacity:0.5; 3 } 4 img:hover{ 5 opacity:1; 6 }
透明圖像的懸停效果在網站中應用還是十分普遍的,尤其是在一些電商網站中,特賣商品或其他商品的展示就可以使用這種效果,京東做過這種效果,淘寶也在使用這種效果展示商品。該效果也可以用 JS 來更改元素的透明度,給圖像綁定鼠標移入移出事件,當鼠標懸停在圖像上時會發生什么。
(3)、圖片畫廊
圖片畫廊也可以叫圖片庫,非常適合作為圖片展示、個人作品展示和相冊使用,可以在頁面上顯示系列圖片,因此圖片畫廊也是網站重要的組成部分,實現圖片畫廊有很多種方法,這里就簡單的用 CSS 創建一個圖片畫廊,如果使用 CSS3 可以讓圖片畫廊擁有更加炫酷的效果。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <base target='_blank'> 6 <title>CSS 圖片畫廊</title> 7 <style> 8 .gallery{ 9 width:auto; 10 height:auto; 11 margin:2px; 12 border:1px solid #0000FF; 13 text-align:center; 14 float:left; 15 } 16 .gallery img{ 17 margin:5px; 18 border:1px solid #FFFFFF; 19 } 20 a:hover img{ 21 border:1px solid #4169E1; 22 } 23 .desc{ 24 width:120px; 25 margin:2px; 26 } 27 </style> 28 </head> 29 <body> 30 <div class="gallery"> 31 <a href="#" target="_blank"><img src="images/1.jpg" alt="anime" width="90" height="90"></a> 32 <div class="desc">在這里可以為圖片添加相關描述。</div> 33 </div> 34 <div class="gallery"> 35 <a href="#" target="_blank"><img src="images/2.jpg" alt="anime" width="90" height="90"></a> 36 <div class="desc">在這里可以為圖片添加相關描述。</div> 37 </div> 38 <div class="gallery"> 39 <a href="#" target="_blank"><img src="images/3.jpg" alt="anime" width="90" height="90"></a> 40 <div class="desc">在這里可以為圖片添加相關描述。</div> 41 </div> 42 <div class="gallery"> 43 <a href="#" target="_blank"><img src="images/4.jpg" alt="anime" width="90" height="90"></a> 44 <div class="desc">在這里可以為圖片添加相關描述。</div> 45 </div> 46 </body> 47 </html>
下圖是瀏覽器顯示結果:

12、CSS 圖像拼合技術
圖像拼合就是 CSS 雪碧 即 CSS Sprite,也被稱為 CSS 精靈,是一種 CSS 圖像合並技術,該方法是將小圖標和背景圖片合並到一張圖片上,然后利用 CSS 的背景定位來顯示需要顯示的圖片部分。簡單說圖像拼合就是單個圖像的集合,他能合並的只能是用於背景的圖片。
有許多圖像的網頁可能需要很長的時間來加載和生成多個服務器的請求,那么使用圖像拼合就會減少網站的 HTTP 請求數量,提高頁面加載速度,並節省帶寬。
圖像拼合的原理就是把頁面涉及到的所有零星圖片整合在一張大圖中,圖片在 CSS 中定義,而不是使用 <img> 標簽。利用 CSS 的 background-image、background- repeat、background-position 屬性的組合進行背景定位,background-position 使用數字可以精確的定位出背景圖片需要顯示的位置。合圖的一般順序為從上到下、從左到右,通常保存為 PNG 格式的文件。使用 CSS Sprite 時一定要預先確定每個小圖標的大小,並且要注意每個圖標之間的間距。
(1)、簡單實例
在網站中應用 CSS Sprite,那么首先就得把需要的圖片合並成一張圖片,可以使用 PS 手動合成,也可以下載用於生成 CSS Sprite 的本地應用,比如 CssGaga 等,還可以使用一些簡單的在線 CSS Sprite 生成工具,比如 CSS Sprites Generator 或 GoPng ,前者是一個小清新風格的網站,簡單的界面和綠色背景,使用非常方便,易操作,但是圖片只能橫向或縱向排列,不支持圖片拖拽排列,支持自定義圖片間距,點擊生成按鈕之后,頁面下方會自動生成每張圖片的樣式信息方便調用,點擊 PNG 圖標下載圖片,另外點擊 HTML 圖標可以跳轉新頁面預覽生產的圖標。后者是企鵝的前端使用 HTML5 實現的合成圖片的在線工具,支持自定義畫布大小,帶有磁力吸附對齊功能,可以拖動圖片進行排序,不僅能生成 PNG 圖片,還可以生成 CSS 文件,並且還能定制 CSS 模板,支持工作狀態導出,包括圖片數據(圖片、圖片位置排序)和參數設置(主頁的參數設置和 CSS 模板設置)全部導出成一個文件,下次利用該文件就可以恢復到上次的工作狀態。企鵝的工具明顯相當強大了,一般情況是足夠用了,界面也比較清爽,就是個人感覺不太好操作。
下圖是在百度圖片中找的幾個小圖標,使用企鵝的在線工具生成的 CSS Sprite 圖,在下面例子中使用。

使用圖像拼合技術是小圖片加載優化的慣用手段,上面的雪碧圖是把7個小圖標合並在一個圖片中,使用這種單個的圖片,再利用 CSS,就可以只顯示我們需要的部分:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>CSS Sprite</title> 6 <style> 7 i{ 8 width:64px; 9 height:64px; 10 display:block; 11 float:left; 12 margin-right:20px; 13 background:url(images/sprite.png) no-repeat; 14 } 15 .clock{ 16 background-position:0 0; 17 } 18 .right{ 19 background-position:0 -64px; 20 } 21 .left{ 22 background-position:0 -128px; 23 } 24 .home{ 25 background-position:0 -192px; 26 } 27 28 .favorite{ 29 background-position:-64px 0; 30 } 31 .love{ 32 background-position:-64px -64px; 33 } 34 .close{ 35 background-position:-64px -128px; 36 } 37 </style> 38 </head> 39 <body> 40 <i class="clock"></i> 41 <i class="right"></i> 42 <i class="left"></i> 43 <i class="home"></i> 44 <i class="favorite"></i> 45 <i class="love"></i> 46 <i class="close"></i> 47 </body> 48 </html>
上面的代碼,在瀏覽器打開后,雪碧圖每個小圖標從上往下並左浮動顯示,右外邊距 20px。
實例解析:
①、雪碧圖中每個小圖標都為等寬等高的圖像,為所有 i 元素都設置 width:64px;height:64px;,定義我們使用的那部分圖像。
②、從代碼中可以看出,雪碧圖應用的語法為:
background:url(images/sprite.png) no-repeat 0 0;
background-image:url(images/sprite.png); 指定了元素的背景圖像,background-repeat:no-repeat; 規定背景圖像不重復,background-position:0 0; 設置背景圖像的位置。
③、background-position:0 0; 定義背景圖像和它的位置(左0px,頂部0px)。
整個 Sprite 圖默認以左上角為坐標點(0,0),即 background-position 代表圖片的起始位置,從左上角開始,x 軸向右為正,y 軸向下為正,所以一般 Sprite 值均為負值。background-position 的計算是指 0 點到圖片左上角的偏移量,例如(-64px,-128px)就是整塊雪碧圖向左(x 軸)移動 64px ,向上(y軸)移動 128px,圖片定位的原理,使用 px 為單位,這個值是一個偏移量,而不是具體的坐標值,正值向正軸方向偏移,負值則相反。
這是使用圖像拼合最簡單的方法,雪碧圖在網站中應用非常廣泛,比如用戶登錄注冊按鈕,圖標導航,電商網站的爆款、熱賣、秒殺和搶購等的小圖片,雪碧圖可以把網站中涉及到的所有零星的小圖標、背景圖像合並在一張大圖中使用,根據實際需要也可以合並為多張圖。
(2)、懸停效果
:hover 選擇器可用於鼠標懸停在元素上顯示的效果,該選擇器可以運用於所有元素。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>CSS Sprite 懸停效果</title> 6 <style> 7 i{ 8 width:64px; 9 height:64px; 10 display:block; 11 float:left; 12 margin-right:20px; 13 background:url(images/sprite.png) no-repeat; 14 opacity:1; 15 } 16 .right{ 17 background-position:0 -64px; 18 } 19 .home{ 20 background-position:0 -192px; 21 } 22 .love{ 23 background-position:-64px -64px; 24 } 25 .left{ 26 background-position:0 -128px; 27 } 28 .favorite{ 29 background-position:-64px 0; 30 } 31 32 i:hover{ 33 opacity:0.3; 34 border:1px solid black; 35 } 36 .change:hover{ 37 background-position:-64px -128px; 38 } 39 </style> 40 </head> 41 <body> 42 <i class="right change"></i> 43 <i class="home"></i> 44 <i class="love"></i> 45 <i class="left change"></i> 46 <i class="favorite change"></i> 47 </body> 48 </html>
上面的代碼,打亂了小圖標的顯示順序,並且用1個小圖標為帶有 change 的類做了鼠標懸停效果,還增加了1像素的邊框,也可以增加外邊距,需要注意鼠標滑過圖片時,為元素增加了邊框會影響外邊距,這樣做可以變相的為靜態圖片增加動態效果,但是這只是一個演示效果,在實際的網站開發中有時僅1像素的問題就會影響到整體的布局結構,需要謹慎使用。
(3)、圖標導航
可以使用雪碧圖創建一個簡單的圖標導航:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>CSS Sprite 圖標導航</title> 6 <style> 7 ul li{ 8 list-style:none; 9 width:64px; 10 height:64px; 11 float:left; 12 margin-right:10px; 13 background:url(images/sprite.png) no-repeat; 14 opacity:1; 15 } 16 ul li a{ 17 display:block; 18 height:64px; 19 } 20 #home{ 21 background-position:0 -192px; 22 } 23 #left{ 24 background-position:0 -128px; 25 } 26 #right{ 27 background-position:0 -64px; 28 } 29 #favorite{ 30 background-position:-64px 0; 31 } 32 #close{ 33 background-position:-64px -128px; 34 } 35 ul li:hover{ 36 opacity:0.5; 37 } 38 </style> 39 </head> 40 <body> 41 <ul> 42 <li id="home"><a href="#" title="主頁"></a></li> 43 <li id="left"><a href="#" title="前進"></a></li> 44 <li id="right"><a href="#" title="后退"></a></li> 45 <li id="favorite"><a href="#" title="收藏"></a></li> 46 <li id="close"><a href="#" title="關閉"></a></li> 47 </ul> 48 </body> 49 </html> 50 51 52 53 <br><br><br><br> 54 ① 55 ② 56 ③ 57 ④ 58 ⑤ 59 ⑥ 60 ⑦ 61 ⑧ 62 ⑨ 63 ⑩
上面代碼中,每個列表項都包含一個鏈接,也可以使用 :hover 偽類讓每個鏈接切換背景圖:
1 #home a:hover{background:url(images/icon.png) no-repeat 0 0;} 2 #left a:hover{background:url(images/icon.png) no-repeat 0 -64px;}
(4)、雪碧圖應用
一些電商網站的導航欄都位於頁面左邊,每項菜單前邊都有一個小背景圖,這就可以使用雪碧圖完成。下面是需要用的圖片:

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>CSS Sprite 應用</title> 6 <style> 7 *{margin:0;padding:0;} 8 nav{ 9 width:150px; 10 background:#F5F5F5; 11 border:1px solid #A9A9A9; 12 margin:20px; 13 } 14 ul{ 15 list-style:none; 16 overflow:hidden; 17 } 18 li{ 19 border-bottom:1px solid #C0C0C0; 20 } 21 li:last-child{ 22 border-bottom:none; 23 } 24 a{ 25 display:block; 26 height:35px; 27 line-height:35px; 28 font-size:14px; 29 font-weight:400; 30 color:black; 31 text-decoration:none; 32 } 33 a:hover{ 34 color:red; 35 background:#DCDCDC; 36 } 37 li i{ 38 float:left; 39 width:24px; 40 height:24px; 41 margin:5px 10px 0 20px; 42 background:url("images/sprite.png") no-repeat; 43 } 44 .icon-1 i{background-position:0 0;} 45 .icon-2 i{background-position:0 -24px;} 46 .icon-3 i{background-position:0 -48px;} 47 .icon-4 i{background-position:0 -72px;} 48 .icon-5 i{background-position:0 -96px;} 49 .icon-6 i{background-position:0 -120px;} 50 .icon-7 i{background-position:-24px 0;} 51 .icon-8 i{background-position:-24px -24px;} 52 .icon-9 i{background-position:-24px -48px;} 53 .icon-10 i{background-position:-24px -72px;} 54 .icon-11 i{background-position:-24px -96px;} 55 .icon-12 i{background-position:-24px -120px;} 56 </style> 57 </head> 58 <body> 59 <nav> 60 <ul> 61 <li class="icon-1"> 62 <i></i> 63 <h3><a href="#">家用電器</a></h3> 64 </li> 65 <li class="icon-2"> 66 <i></i> 67 <h3><a href="#">手機數碼</a></h3> 68 </li> 69 <li class="icon-3"> 70 <i></i> 71 <h3><a href="#">電腦辦公</a></h3> 72 </li> 73 <li class="icon-4"> 74 <i></i> 75 <h3><a href="#">潮流服飾</a></h3> 76 </li> 77 <li class="icon-5"> 78 <i></i> 79 <h3><a href="#">母嬰玩具</a></h3> 80 </li> 81 <li class="icon-6"> 82 <i></i> 83 <h3><a href="#">護膚彩妝</a></h3> 84 </li> 85 <li class="icon-7"> 86 <i></i> 87 <h3><a href="#">鞋包皮具</a></h3> 88 </li> 89 <li class="icon-8"> 90 <i></i> 91 <h3><a href="#">運動戶外</a></h3> 92 </li> 93 <li class="icon-9"> 94 <i></i> 95 <h3><a href="#">汽車用品</a></h3> 96 </li> 97 <li class="icon-10"> 98 <i></i> 99 <h3><a href="#">美食旅游</a></h3> 100 </li> 101 <li class="icon-11"> 102 <i></i> 103 <h3><a href="#">圖書音響</a></h3> 104 </li> 105 <li class="icon-12"> 106 <i></i> 107 <h3><a href="#">金融理財</a></h3> 108 </li> 109 </ul> 110 </nav> 111 </body> 112 </html>
(5)、CSS Sprite 總結
在網頁中,沒請求一次,即沒加載一張圖片,就會個服務器鏈接一次,建立鏈接是需要額外的時間,使用雪碧圖可以加速網站的顯示效果,他最根本的目的就是有效減少 HTTP 請求數量,加速內容顯示。
一些大圖,比如動態圖片或者用戶上傳的圖片不能拼成雪碧圖,雪碧圖適用於以下幾種情況:
①、靜態圖片,不隨用戶信息的變化而變化,在網站上以常態形式存在。
②、小圖片,圖片容量比較小,一般大小為 3-5K,或 3.5K 以下的圖片。
③、加載量比較大的圖片。
Css Sprite 雪碧圖,其實就是將小圖標放在同一個 PSD 文件里,PSD 屬於分層的可編輯的圖片格式,通常需要使用 PS 或 FW 軟件打開,就可以分離圖層。透明背景的小圖片都需要保存為 PNG 格式,他是圖片格式的一種,常被用來作為網頁的圖標。
Css Sprite 的原理,以雪碧圖左上角為基准(0,0),通過 background-position 設置 x、y 偏移來顯示需要的部分,x 向右為正,y 向下為負,所以一般都為負值。
13、CSS 導航欄
擁有易用的導航欄,對於任何網站都非常重要。通過 CSS 可以把枯燥的 HTML 菜單轉換成漂亮的導航欄。
(1)、導航欄 - 鏈接列表
導航欄需要標准的 HTML 作為基礎,對於前端開發人員而言,一定要熟悉 Web 標准。
導航欄基本上是一個鏈接列表,所以使用 <ul> 和 <li>元素非常適合,根據實際開發需求也可以使用自定義列表創建導航欄。
下面是創建導航欄鏈接列表的標准 HTML 結構:
1 <ul> 2 <li><a href="URL">HTML</a></li> 3 <li><a href="URL">CSS</a></li> 4 <li><a href="URL">JavaScript</a></li> 5 <li><a href="URL">jQuery</a></li> 6 </ul>
一個導航欄並不需要列表標記,並且需要初始化列表的樣式,即清除列表的填充和外邊距,這些都需要使用 CSS 定義:
1 ul{ 2 list-style:none outside; 3 padding:0; 4 margin:0; 5 }
這里僅僅只是初始化了列表的樣式,在實際的網站開發中,需要對整個 HTML 文檔進行初始化設置。
(1)、垂直導航欄
垂直導航欄通常都位於網站左側,也可以叫左側導航欄。如果需要構建垂直導航欄,只需要給 a 元素定義樣式就可以了。因為 a 元素為內聯元素,所以首先就需要把他轉換為塊元素,使用 CSS 定義 display:block ,即顯示塊元素的鏈接,讓整體變為可點擊鏈接區域,不只是鏈接文本。塊元素默認情況下,是最大寬度,所以必需給導航欄指定寬度,再添加其他用於美化的樣式。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>左側導航欄</title> 6 <style> 7 *{padding:0;margin:0;} 8 ul{ 9 list-style:none outside; 10 } 11 a{ 12 display:block; 13 background:#99CC33; 14 width:120px; 15 height:35px; 16 line-height:35px; 17 color:white; 18 font-weight:bold; 19 text-decoration:none; 20 text-align:center; 21 } 22 a:hover{ 23 color:black; 24 background-color:#669933; 25 } 26 </style> 27 </head> 28 <body> 29 <ul> 30 <li><a href="URL">IT互聯網</a></li> 31 <li><a href="URL">職業技能</a></li> 32 <li><a href="URL">語言學習</a></li> 33 <li><a href="URL">設計創作</a></li> 34 <li><a href="URL">興趣愛好</a></li> 35 <li><a href="URL">職業規划</a></li> 36 </ul> 37 </body> 38 </html>
現有的網站中,有一部分網站構建的左側導航欄,並不是使用標准的 HTML 鏈接列表來布局的,而是使用 DIV 來完成的,比如京東商城左側的導航欄,就使用的 DIV 嵌套標題鏈接布局的,也有一些網站是直接在 DIV 中嵌套鏈接,還有一些網站是通過一個列表項再嵌套 DIV 的方式來布局的,這樣雖然都能達到目的,但嚴格來講並不符合標准,大多數情況下左側導航欄在鼠標移入時,都會在右側顯示該菜單欄的相關選項,與京東商城類似的比如蘇寧、國美、小米的左側導航欄都是使用標准的 HTML 鏈接列表來布局的。而淘寶網左側的導航欄布局使用的是自定義鏈接列表,這也符合 HTML 標准。幾乎所有網站構建的水平導航欄都是使用標准的 HTML 鏈接列表布局的。
(2)、水平導航欄
有兩種創建水平導航欄的方法,使用內聯或浮動的列表項。這兩種方法都很好,但如果需要每個菜單項都擁用有相同的大小,就必須使用浮動的方法。
①、內聯列表項
創建一個水平導航欄的方法之一是就是把 li 元素轉換為內聯元素,默認 li 元素是塊級元素,所以使用 CSS 設置 display:inline; 可以刪除每個列表項之前和之后的換行符,以顯示一行 。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>內聯水平導航欄</title> 6 <style> 7 *{padding:0;margin:0;} 8 ul{ 9 list-style:none outside; 10 padding:10px 0; 11 } 12 li{ 13 display:inline; 14 } 15 a{ 16 background:#0000CD; 17 color:white; 18 font-weight:bold; 19 text-decoration:none; 20 padding:10px; 21 } 22 a:hover{ 23 background-color:#191970; 24 } 25 </style> 26 </head> 27 <body> 28 <ul> 29 <li><a href="URL">首頁</a></li> 30 <li><a href="URL">公司簡介</a></li> 31 <li><a href="URL">經營發展</a></li> 32 <li><a href="URL">產品展示</a></li> 33 <li><a href="URL">新聞中心</a></li> 34 <li><a href="URL">在線服務</a></li> 35 <li><a href="URL">企業文化</a></li> 36 </ul> 37 </body> 38 </html>
這里需要注意:如果只給 a 元素設置內邊距,而不給列表設置,那么鏈接會出現在 ul 元素之外,所以必須給 ul 設置頂和底內邊距。
②、浮動列表項
使用內聯列表項,鏈接的寬度是不同的,為了讓所有鏈接擁有相等的寬度,需要給 li 元素設置浮動,並把 a 元素轉換為塊元素再指定寬度。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>浮動水平導航欄</title> 6 <style> 7 *{padding:0;margin:0;} 8 ul{ 9 list-style:none outside; 10 overflow:hidden; 11 } 12 li{ 13 float:left; 14 } 15 a{ 16 display:block; 17 background:#CCCCCC; 18 width:120px; 19 height:35px; 20 line-height:35px; 21 color:black; 22 font-weight:bold; 23 text-decoration:none; 24 text-align:center; 25 margin-right:2px; 26 } 27 a:hover{ 28 color:white; 29 background-color:#000000; 30 } 31 </style> 32 </head> 33 <body> 34 <ul> 35 <li><a href="URL">首頁</a></li> 36 <li><a href="URL">公司簡介</a></li> 37 <li><a href="URL">經營發展</a></li> 38 <li><a href="URL">產品展示</a></li> 39 <li><a href="URL">新聞中心</a></li> 40 <li><a href="URL">在線服務</a></li> 41 <li><a href="URL">企業文化</a></li> 42 </ul> 43 </body> 44 </html>
14、CSS 媒體類型
媒體類型(Media Type)是用於指定文件將如何在不同媒體呈現。該文件可以以不同的方式顯示在屏幕上,在紙張上,或聽覺瀏覽器等等。
一些 CSS 屬性僅僅被設計為針對某些媒體。例如 "voice-family" 屬性被設計為針對聽覺用戶終端,其他一些屬性可用於不同的媒體類型。例如,"font-size" 屬性可用於屏幕和印刷媒體,但有不同的值。屏幕和紙上的文件不同,所以屏幕上顯示的文檔通常需要比紙媒體文檔更大的字體,因此針對不同的媒體,需要使用不同的字體系列,使文本更易閱讀。再比如電腦端和移動終端,因為屏幕尺寸的不同,所以更需要針對不同的設備定義不同的樣式,即響應式布局。
(1)、@media 規則
@media 規則使你有能力在相同的樣式表中,使用不同的樣式規則來針對不同的媒體,簡單說就是:可以在相同樣式表為不同媒體設置不同的樣式。
下面的樣式,使用 @media 規則指定在瀏覽器中段落顯示為”14px“的”微軟雅黑“字體,如果頁面被打印,則段落顯示為”10px“的”宋體“,不管是在瀏覽器頁面上還是在紙上段落都被顯示為加粗:
1 @media screen{ 2 p{ 3 font-family:"Microsoft YaHei",Arial,Tahoma,sans-serif; 4 font-size:14px; 5 } 6 } 7 8 @media print{ 9 p{ 10 font-family:'宋體'; 11 font-size:10px; 12 } 13 } 14 15 @media screen,print{ 16 p{font-weight:bold;} 17 }
(2)、不同的媒體類型
| 媒體類型 | 說明 |
| all | 用於所有設備。 |
| screen | 用於電腦屏幕,平板電腦,智能手機等。 |
| speech | 應用於屏幕閱讀器等發聲設備。 |
| 用於打印機和打印預覽。 |
注意:媒體類型不區分大小寫。
15、CSS 重要性
(1)、CSS 繼承
CSS 的某些屬性是具有繼承性的,繼承是一種規則,它允許樣式不僅應用於某個特定html標簽元素,而且應用於其后代。
比如下面的例子,給 p 標簽設置字體顏色,這個顏色設置不僅應用 p 標簽,還應用於 p 標簽中的所有子元素文本。
1 <head> 2 <style> 3 p{ 4 color:red; 5 border:1px solid black; 6 } 7 </style> 8 </head> 9 <body> 10 <p>CSS 的某些屬性是具有繼承性的,<span>繼承是一種規則,</span>它允許樣式不僅應用於某個特定 HTML 標簽元素,而且應用於其后代。</p> 11 </body>
需要注意,有一些 CSS 樣式是不具有繼承性的,比如 border:1px solid black;。
(2)、CSS 特殊性
有時候我們為同一個元素設置了不同的 CSS 樣式代碼,瀏覽器會根據權值來判斷使用哪種 CSS 樣式,哪種樣式權值高就使用該樣式,所以理解選擇器的特殊性很重要。
權值就是所用選擇器的特殊性,瀏覽器會根據這種特殊性來決定所定義的樣式規則的次序,具有更特殊選擇器的規則優先於具有一般選擇器的規則,如果兩個規則的特殊性相同,那么后定義的規則優先,這一點和 JS 相同,即后面定義的會覆蓋前邊定義的。
覆蓋也就是 CSS 層疊,當有相同權重的樣式存在時,會根據這些 CSS 樣式的前后順序來決定,處於最后面的 CSS 樣式會被應用。那么對於 CSS 樣式優先級的順序就不難理解了。
特殊性可以分為4個等級,每個等級代表一類選擇器:
①、代表內聯樣式,如 <p style="color:red"></p>,權值為 1000。
②、代表 ID 選擇器,如 #content,權值為 100。
③、代表類,類選擇器以及偽類和屬性選擇器,如 .main,權值為 10。
④、代表類型選擇器,標簽和偽元素選擇器,如 div p,權值為 1。
通配符選擇器(*),子選擇器(>)和相鄰同胞選擇器(+)並不在這四個等級中,所以他們的權值都為 0。
注意:繼承也有權值的,但是繼承的權值是最低的。
每個等級的值為其所代表的選擇器的個數乘以這一等級的權值(比如 ④ 中例子的權值為 2),最后把所有等級的值相加得出選擇器的特殊值。比較同一級別的個數,數量多的優先級高,如果相同即比較下一級別的個數 。
權值的規則:選擇器的權值相加,大的優先;如果權值相同,后定義的優先 。
權值的大小跟選擇器的類型和數量有關,樣式的優先級跟樣式的定義順序有關。
1 p{ /* 權值為 1 */ 2 color:red; 3 } 4 p span{ /* 權值為 1+1=2 */ 5 color:green; 6 } 7 .main{ /* 權值為 10*/ 8 font-size:14px; 9 } 10 div p .main{ /* 權值為 1+1+10=12 */ 11 color:purple; 12 } 13 #footer{ /* 權值為 100 */ 14 color:gray; 15 } 16 #footer .note p{ /* 權值為 100+10+1=111 */ 17 color:white; 18 }
(3)、CSS 重要性
在實際的網站開發中,有些特殊的情況需要為某些樣式設置具有最高權值,這時候我們可以使用 !important 來解決。
具體實現如下:
1 <head> 2 <style> 3 p{ 4 color:red!important; 5 } 6 .demo{ 7 color:green; 8 } 9 </style> 10 </head> 11 <body> 12 <p class="demo">在實際的網站開發中,有些特殊的情況需要為某些樣式設置具有最高權值,這時候我們可以使用 !important 來解決。</p> 13 </body>
上面的代碼,使用標簽選擇器設置了段落字體為紅色,再使用類選擇定義了段落字體為綠色,標簽選擇器的權值為 1,類選擇器的權值為 10,因為類選擇器的權值更高,最終段落顯示為綠色,但是我們使用了 important,這時段落中的文字就顯示為紅色。
!important 擁有最高權值,需要注意,在使用時不能忘了前邊的感嘆號,並且要寫樣式的分號前邊。
當網頁不設置 CSS 樣式時,瀏覽器會按照自己的一套樣式來顯示網頁。並且用戶也可以在瀏覽器中設置自己習慣的樣式,比如有的用戶習慣把字號設置為大一些,使其查看網頁的文本更加清楚。這時樣式優先級為:瀏覽器默認的樣式 < 網頁的樣式 < 用戶自己設置的樣式,但 !important 優先級樣式是個例外,權值高於用戶自己設置的樣式。
