結構與層疊
每個合法的文檔都會生成一個結構樹,有了結構樹元素的祖先、屬性兄弟元素等等創建選擇器來選擇元素,這是CSS繼承的核心。繼承是從一個元素向後代元素傳遞屬性值所采用的機制。面向一個元素使用哪些值時,用戶代理不僅要考慮繼承,還要考慮特殊性,另外需要考慮聲明本身的來源,這個過程就叫層疊。
本文討論3種機制之間的關聯:特殊性、繼承和層疊。
特殊性
同一元素可以使用不同的方法來選擇元素。但是每個規則,用戶代理會計算選擇器的特殊性,並將這個特殊性附加到規則的個個聲明。如果一個元素有兩個或多個沖突的屬性聲明,那麼最高特殊性的聲明會勝出。
特殊性計算規則:
1)對於選擇器中給定的各個ID屬性值,加0100
2)對於選擇器中給定的各個類屬性值,屬性選擇或偽類,加0010
3)對於選擇器中給定的各個元素和偽元素,加0001
4)結合符和通配選擇器對特殊性沒有任何貢獻
對於重疊的選擇,如果符合多種規則,這些規則將累加計算。0011特殊性優於0001,0100優於0022。這是因為值從左向右排序。
題目:下列選擇器同指向同一元素,容器的顏色應該為什麼顏色?
CSS Code復制內容到剪貼板考察特殊性,答案#333399;特殊性分別為:0022,0011,0101,0100,0112
注意:特殊性不是解決沖突的全部,實際上,所有樣式沖突的解決都由層疊來處理。
到目前為止,我們只見過以0開頭的特殊性。一般地,第一個0是為內聯樣式聲明保留的,他比所有其他聲明的特殊性都高。
CSS Code復制內容到剪貼板有時候某個聲明可能非常重要,超過了所有其他聲明,並允許在這些聲明的結束分號之前插入!important來標志。
CSS Code復制內容到剪貼板當樣式表增設!important時,內聯沖突樣式將會失效,以important為准。
繼承
基於繼承機制,樣式不僅應用到指定的元素,還會應用到它的後代元素。
一般地,大多數框模型屬性(包括外邊距、內邊距、背景和邊框)都不能繼承,其原因是因為如果這些屬性被繼承,文檔將會變得更加混亂。
繼承的值根本沒有特殊性,甚至連0特殊性都沒有。(0特殊性比無特殊性要強)
不加區別地使用通配選擇器可能存在的問題之一,由於他能匹配任何袁術,所以通配選擇器往往有一種短路繼承的效果。
層疊
如果特殊性相等的兩個規則相同同時應用到同一個元素,浏覽器會通過層疊解決這個沖突。
CSS所基於的方法就是讓樣式層疊在一切,這是通過結合繼承和特殊性做到的。層疊的規則:
1)找出所有相關的規則,這些規則都包含與一個給定元素匹配的選擇器。
2)按顯式權重對應用到該元素的所有聲明排序。標志!important的規則的權重要高於沒有 !important標志的規則。聲明權重考慮5級:(權重有大到小順序依次為)
1.讀者的重要聲明
2.創作人員的重要聲明
3.創作人員的正常聲明
4.讀者的正常聲明
5.用戶代理聲明
3)按特殊性對應用到給定元素的所有聲明排序。有較高特殊性的元素權重要大於有較低特殊性的元素。
4)按出現順序對應用到給定元素的所有聲明順序。一個聲明在樣式表或文檔中越後出現,他的權重就越大。。如果樣式表中有導入的樣式表,一般認為出現在導入樣式表中的聲明在前,在主樣式表中的所有聲明在後。
注意:多類選擇符,以空格分割不同的類名,但是根據層疊的規則,元素中的類的順序無關,而是與樣式表聲明的位置有關。
CSS Code復制內容到剪貼板red和blue和yellow設置沖突的背景顏色屬性,但是,box最終顯示的顏色和Html中這三個類順序無關。聲明樣式表如下:
CSS Code復制內容到剪貼板box最終顯示的顏色以聲明的順序有關,最終顯示為blue背景顏色。
基本視覺格式化
CSS包含如此開放、如此強大的一個模型,對於這樣一個模型,可以有無數種方法結合應用各種屬性,可以得到的效果數不勝數。
基本框
CSS假定每個元素都會生成一個或多個矩形框,這稱為元素框。各元素中心有一個內容區,這個內容區周圍包含可選的內外邊距和邊框(之所以認為是可選,是因為可以設置為0)。
對不同類型的元素格式化時存在著差別。塊級元素的處理就不同於行內元素,而浮動元素和定位元素也分別有各自不同的表現。
包含塊
每個元素都相當於包含塊擺放;可以這麼說,包含塊就是一個元素的”布局上下文“,CSS2.1定義了一系列規則來確定元素的包含塊。
常用名詞:
正常流,文本從左向右,從上向下顯示。要讓一個元素不在正常流中,唯一的辦法是使之成為浮動或定位元素。
非替換元素,如果元素的內容包含在文檔中,則稱之為非替換元素。
替換元素,指用作為其他內容占位符的一個元素。替換元素的一個經典例子就是img元素。它只是指向一個圖像文件,這個文件將插入到文檔流中該img元素本身的位置。
塊級元素,這是指段落、標題或div之類的元素。這個元素在正常流中,會在其框之前和之後生成”換行“,所以處於正常流中的塊級元素會垂直擺放。通過聲明display:block,可以讓元素生成塊級框。
行內元素,這是指strong或span之類的元素。這個元素不會在之前或之後生成”行分割符“,它們是塊級元素的後代。通過聲明display:inline,可以讓元素生成vyige行內框。
根元素,位於文檔流頂端的元素,在html文檔中,這就是元素Html。
塊級元素-水平格式化
width並不是指可見元素框的寬度,如果為一個元素聲明了內編劇、邊框以及寬度,他們指定的寬度則是左外邊界到右外邊界的距離。可以通過設定box-sizing:content-box來模擬IE6的怪異現象,即使得元素的寬度為實際設置的寬度width,而不是width+padding+border。
使用auto
CSS Code復制內容到剪貼板假設padding-left(padding-right)、margin-left(margin-rignt)、width,border-left-right(border-right)七個屬性的和必須等與外容器的寬度,即400px,設置左邊距auto,那麼左邊距的寬度將是200px。就是說,auto是用來”填補“所需的距離,使元素的總寬度等於其包含塊的width。
CSS Code復制內容到剪貼板效果如下:
因此,如果設置margin-left和margin-right都為auto:
將兩個外邊距設置為相等的長度是將元素居中的一個正確方法,這不同於使用text-align(text-align只應用與塊級元素的內聯內容,所以將元素的text-align設置為center並不能將這個元素居中)。
如果設置width和marin-left都為auto,那麼margin-left將會被設置為0:
CSS Code復制內容到剪貼板設置負外邊距,
CSS Code復制內容到剪貼板width的值為400px-100px(+margin-left)+100px。因為marin-left的為負值,因此content的實際width要加上(負的margin-left值)
塊級元素-垂直格式化
一個元素默認的高度由其內容決定。高度還會受內容寬度的影響;段落越窄,相應地就會越高,以便容納其中所有的內聯內容。
如果正常流中一個塊元素的margin-top或margin-bottom設置為auto,它會自動計算為0.遺憾的是,如果值為0,就不能你容易地將正常流元素在其包含塊中居中。也就是說,如果將一個元素的上、下外邊距設置為auto。實際上它們都會被重置為0,使得元素沒有外邊距。
合並垂直外邊距
垂直格式化的另一個重要方面是垂直相鄰外邊距的合並。這種合並性為只應用於外邊距。如果元素有內邊距和邊框,它們絕對不會合並。
舉個例子,一個無序列表,其列表項前後相鄰。
CSS Code復制內容到剪貼板每個列表項有10px的上外邊距和15px的下外邊距。不過,在顯示這個列表時,相鄰列表項之間的距離是15px而不是25px:
之所以會這樣,是因為相鄰外邊距會沿著豎起軸合並。換句話,兩個外邊距中較小的一個會被比較大的一個合並。
如果相鄰有多個外邊距,也會出現合並,如列表的最後。對前面的例子進行補充,假設應用一下規則:
最後列表合並外邊距為28px.
如果其中一個外邊距為負數,那麼實際外邊距就是最大的外邊距減去負數外邊距的絕對值。
行內元素的行布局
對於行內元素來說,這沒有塊級元素那麼簡單和直接,塊級元素知識生成框,通常不允許其他內容與這些框並存。
文本使用text-align進行兩端對其時,Word-spacing的值可能被覆蓋(如果letter-spacing是一個長度值,這個值不能被覆蓋)。
基本術語和概念
匿名文本,是指所有未包含在行內元素中的字符串<p>I'm<em>so</em>happy!</p>
序列中I'm和happy!都是匿名文本。
em框,em框在字體中定義,也成為字符框。實際的字形可能比其em框更高或更矮。
內容區,在非替換元素中,內容區可能有兩種。內容區可以是元素中個字符的em框串在一起構成的框,也可以是由元素中字符字形描述的框。
行間距,是font-size值和line-height值只差,這個差實際上要分為兩半,分別應用到內容區的頂部和底部。為內容區增加的這兩部分分別稱為版兼具。行內距只應用於非替換元素。
行內框,這個框通過向內容區增加行間距來描述。對於非替換元素,袁術行內框的高度剛好等於line-height的值。對於替換元素,元素行內框的高度則恰好等於內容區的高度,因為行間距不應用到替換元素。
行框,這個包含該行中出現的行內框的最高點和最低點的最小框。換句話說,行框的上邊界要位於最高行內框的上邊界,而行框的底邊要放在最低行內框的下邊界。
1)內容區類似於一個塊級元素的內容框。
2)行內元素的背景應用於內容區及所有內邊距。
3)行內元素的邊框要包圍內容區及所有內邊距和邊框。非替換元素的內邊距、邊框和外邊距對行內元素或其生成的框沒有垂直效果;也就是所它們不會影響元素行內框的高度。
4)替換元素的外邊距和邊框確實會影響該元素行內框的高度,相應地,也可能影響包含該元素的邊框高度。
行內非替換元素
假設有一下標記:
CSS Code復制內容到剪貼板效果如下:
大多數文本的font-size都是12px,只有一個行內非替換元素中的文本大小是24px。不過,所有文本的line-height都是12px,因為line-heght是一個繼承屬性。因此strong元素的line-height也是12px。
由於行內框的頂端在元素內容區內部,所以元素的內容落在了行框的外邊,實際上與其他行框發生了重疊。其結果是,文本行看上去很不規則。
CSS Code復制內容到剪貼板把元素上升4像素,折回同時提升其內容區和行內框。由於strong元素的行內框頂端已經是行中的最高點,對垂直對其的這個修改會把整個行框的頂端也向上移4像素。效果如圖:
垂直對齊影響行框高度。
如果line-height不使用單位,而是用值小於1的數值,那麼line-height將會相對於元素本省font-size設置行高,而不是相對於父元素設置。