久久精品国产亚洲AV成人婷婷_性色av不卡无码一区二区_人妻无码久久影视_久久精品国产免费一卡二卡

網(wǎng)頁的結構和重疊

前面我們介紹了如何利用網(wǎng)頁文檔結構和CSS選擇器為元素應用各種豐富的樣式。每個合法的文檔都會生成一個結構樹,了解了這一點,就能根據(jù)元素的祖先、屬性、兄弟元素等等創(chuàng)建選擇器來選擇元素。有了這個結構樹,選擇器才能起作用,這也是CSS另一個重要方面(即繼承)的核心。

繼承(Inheritance)是從一個元素向其后代元素傳遞屬性值所采用的機制。確定應當向一個元素應用哪些值時,網(wǎng)頁瀏覽器不僅要考慮繼承,還要考慮聲明的特殊性,另外需要考慮聲明本身的來源。這個過程就稱為層疊(cascade)。我們接下來將討論這3種機制之間的關聯(lián):特殊性、繼承和層疊。

特殊性

我們現(xiàn)在知道了可以使用多種不同的方法選擇元素。實際上,可能同一個元素可以使用兩個或多個規(guī)則來選擇,每個規(guī)則都有其自己的選擇器,下面考慮以下3對規(guī)則。假設每一對規(guī)則都匹配同樣的元素:

h1 {color: red;}

body h1 {color: green;}

h2.grape {color: purple;}

h2 {color: silver;}

html > body table tr[id="totals"] td ul > li {color: maroon;}

li#answer {color: navy;}

顯然,每一對規(guī)則中只有一個勝出,因為所匹配的元素只能是某一種顏色(或此或彼)。那么怎么知道哪一個規(guī)則更強呢?

答案就在于每個選擇器的特殊性(specificity)。對于每個規(guī)則,用戶代理會計算選擇器的特殊性,并將這個特殊性附加到規(guī)則中的各個聲明。如果一個元素有兩個或多個沖突的屬性聲明,那么有最高特殊性的聲明就會勝出。

注意:這并不是解決沖突的全部。實際上,所有樣式?jīng)_突的解決都由層疊來處理,本章后面專設了一節(jié)介紹這個內(nèi)容。

選擇器的特殊性由選擇器本身的組件確定。特殊性值表述為4個部分,如:0,0,0,0。一個選擇器的具體特殊性如下確定:

對于選擇器中給定的各個ID屬性值,加0,1,0,0。

對于選擇器中給定的各個類屬性值,屬性選擇或偽類,加0,0,1,0。

對于選擇器中給定的各個元素和偽元素,加0,0,0,1。偽元素是否有特殊性,在這方面css2有些自相矛盾,不過css2.1很清楚的指出,偽元素有特殊性,而且其特殊性為0,0,0,1。

結合符和通配符選擇器對特殊性沒有任何貢獻(后面還會更多地介紹這些值)。

例如,以下規(guī)則中選擇器的特殊性見注釋:

h1{color:red;}/* specifity = 0,0,0,1 */

p em{color:purple;}/* specifity = 0,0,0,2 */

.grape{color:purple;}/* specifity = 0,0,1,0 */

*.bright{color:yellow;}/* specifity = 0,0,1,0 */

p.bright em.dark{color:maroon;}/* specifity = 0,0,2,2 */

#id216{color:blue;}/* specifity = 0,1,0,0 */

div#sidebar *[href]{color:silver;}/* specifity = 0,1,1,1 */

假設有以下情況,一個em元素與上例中的第2條規(guī)則匹配,又與第5條規(guī)則匹配,這個元素將是紫紅色,因為第5條規(guī)則的特殊性高于第2條規(guī)則的特殊性。

下面做個練習,回顧本節(jié)前面給出的幾組規(guī)則,看看它們有怎樣的特殊性:

h1 {color:red;}/* 0,0,0,1 */

body h1 {color:green;}/* 0,1,0,2 (winner)*/

h2.grape{color:purple;}/* 0,0,1,1 (winner)*/

h2 {color:silver;}/* 0,0,0,1 */

html > body table tr[id="totals"] td ul > li {color: maroon;}/* 0,0,1,7 */

li#answer {color: navy;}/* 0,1,0,1 (winner)*/

上面已經(jīng)指出每組規(guī)則中的勝出規(guī)則,在上述各種情況下,那些規(guī)則之所以勝出是因為其特殊性更高。要注意特殊性是如何排序的。在第二組中,選擇器h2.grape能“贏”是因為它多了一個1: 0,0,1,1大于0,0,0,1。在第三組中,第二個規(guī)則勝出是因為0,1, 0,1大于0,0,1,7。實際上,特殊性值0,0,1,0比值0,0, 0,13更高。

之所以會這樣,是因為值是從左向右排序的。特殊性值1,0, 0,0大于以0開頭的所有特殊性值,而不論后面的數(shù)是什么。所以0,1, 0,1比0,0,1,7高,因為前一個值中第二位上的1大于第二個值中第二位上的0。

聲明和特殊性

一旦確定一個選擇器的特殊性,這個值將授予其所有相關聲明。考慮以下規(guī)則:

h1 {color: silver; background: black;}

由于特殊性的緣故,網(wǎng)頁瀏覽器必須相應地處理這個規(guī)則,將其“解組”為單獨的規(guī)則。因此,前面的例子將變成:

h1 {color: silver;}

h1 {background: black;}

這兩個規(guī)則的特殊性都是0, 0 , 0 , 1,各聲明得到的特殊性值也就是0, 0 , 0 , 1。分組選擇器也同樣會完成這種分解過程。給定以下規(guī)則:

h1, h2.section {color: silver; background: black;}

網(wǎng)頁瀏覽器將把它處理為:

h1 {color: silver;}/* 0,0,0,1 */

h1 {background: black;}/* 0,0,0,1 */

h2.section {color: silver;}/* 0,0,1,1 */

h2.section {background: black;}/* 0,0,1,1 */

如果多個規(guī)則與同一個元素匹配,而且有些聲明相互沖突,在這種情況下特殊性就很重要。例如,考慮以下規(guī)則:

h1 + p {color: black; font-style: italic;}/* 0,0,0,2 */

p {color: gray; background: white; font-style: normal;}/* 0,0,0,1 */

*.aside {color: black; background: silver;}/* 0,0,1,0 */

當這些規(guī)則應用到以下標記時,顯示的內(nèi)容將如圖3-1所示:

<h1>Greetings!</h1>

<p class="aside"> It's a fine way to start a day, don't you think?

</p>

<p> There are many ways to greet a person, but the words are not as important as the act of greeting itself.

</p>

<h1>Salutations!</h1>

<p> There is noth1ng finer than a hearty welcome from one's fellow man.

</p>

<p class="aside"> Although a thick and juicy hamburger with bacon and mushrooms runs a close second.

</p>

任何情況下,用戶代理都會確定哪些規(guī)則與一個元素匹配,計算出所有相關的聲明及其特殊性,確定哪些規(guī)則勝出,然后將勝出的規(guī)則應用到元素,從而得到應用樣式后的結果。每個元素、選擇器和聲明上都必須完成這些工作。幸運的是,用戶代理會自動完成所有這些工作。這個行為是層疊的一個重要部分,本章后面還將深入討論層疊。

通配選擇器特殊性

前面提到過,通配選擇器對一個選擇器的特殊性沒有貢獻。換句話說,其特殊性為0,0,0,0,這與根本沒有特殊性有區(qū)別(有關內(nèi)容將在“繼承”一節(jié)中介紹)。因此,給定以下兩條規(guī)則,div下包含的段落將是黑色,而其他元素都是灰色:

div p {color: black;}/* 0,0,0,2 */

*{color: gray;}/* 0,0,0,0 */

如你所料,這意味著如果一個選擇器中包含通配選擇器和其他選擇器,該選擇器的特殊性不會因通配選擇器的出現(xiàn)而改變。下面兩個選擇器的特殊性完全相同:

div p /* 0,0,0,2 */

body * strong /* 0,0,0,2 */

相比之下,結合符則根本沒有特殊性,甚至連0特殊性都沒有。因此,它們對選擇器的總特殊性沒有任何影響。

ID和屬性選擇器的特殊性

需要著重指出,ID選擇器和指定id屬性的屬性選擇器在特殊性上有所不同。再來看示例代碼中的第三組規(guī)則,可以看到:

html > body table tr[id="totals"] td ul > li {color: maroon;}/* 0,0,1,7 */

li#answer {color: navy;}/* 0,1,0,1 {winner}*/

第二個規(guī)則中的ID選擇器(#answer)為選擇器的總特殊性貢獻了0,1, 0,0。而在第一個規(guī)則中,屬性選擇器([id="totals"])只對總特殊性貢獻了0,0,1,0。因此,給定以下規(guī)則,id為meadow的元素將變成綠色:


#meadow {color: green;}/* 0,1,0,0 */

*[id:"meadow"]{color: red;}/* 0,0,1,0 */

內(nèi)聯(lián)樣式特殊性

到目前為止,我們已經(jīng)見過以0開頭的特殊性,所以你可能會奇怪為什么會有這些特殊性。一般地,第一個0是為內(nèi)聯(lián)樣式聲明保留的,它比所有其他聲明的特殊性都高??紤]以下規(guī)則和標記片段:

h1 {color: red;}

<h1 style="color: green?">The Meadow Party</h1>

假設這個規(guī)則應用到h1元素,h1的文本還將是綠色。CSS2.1中就是如此,這是因為每個內(nèi)聯(lián)聲明的特殊性都是1,0, 0,0。

這意味著,即使有id屬性的元素與某個規(guī)則匹配,也必須遵循內(nèi)聯(lián)樣式聲明。下面把上例修改為包括一個id屬性:

h1#meadow {color: red;}

<h1 id="meadow" style="color: green;">The Meadow Party</h1>

由于內(nèi)聯(lián)聲明的特殊性最高,h1元素的文本還是綠色。

注意:為內(nèi)聯(lián)樣式聲明保留一位,這是CSS2.1才新增的,這樣做是為了反映寫CSS2.1當時的Web 瀏覽器表現(xiàn)。在CSS2中,內(nèi)聯(lián)樣式聲明的特殊性是1,0,0 (CSS2特殊性包含3個值,而不是4個)。換句話說,它與ID選擇器的特殊性相同,所以ID選擇器很容易覆蓋內(nèi)聯(lián)樣式。

重要性

有時某個聲明可能非常重要,超過了所有其他聲明。CSS2.1稱之為重要聲明(原因顯而易見),并允許在這些聲明的結束分號之前插入!important來標志。

p.dark {color:#333 !important; background: white;}

在此為顏色值#333加了標志!important,而背景值white未加這個標志。如果你希望把兩個聲明都標志為重要,那么每個聲明都需要它自己的!important標志:

p.dark {color:#333 !important; background: white !important;}

必須正確地放置!important,否則聲明將無效。! important總是放在聲明的最后,即分號前面。如果一個屬性的值可以包含多個關鍵詞,如font,這一點則尤其重要,必須將!important標志放在聲明的最后:

p.light {color: yellow; font: smaller Times, serif !important;}

如果!important放在font聲明的任何其他位置,整個聲明都將無效,相應地不會應用其任何樣式。

標志為!important的聲明并沒有特殊的特殊性值,不過要與非重要聲明分開考慮。實際上,所有!important聲明會分組在一起,重要聲明的特殊性沖突會在重要聲明內(nèi)部解決,而不會與非重要聲明相混。類似地,我們認為所有非重要聲明也歸為一組,使用特殊性來解決沖突。如果一個重要聲明和一個非重要聲明沖突,勝出的總是重要聲明。圖3-2展示了以下規(guī)則和標記片段的結果:

h1 {font-style: italic; color: gray !important;}

.title {color: black; background: silver;}

*{background: black !important;}

<h1 class="title">NightWing</h1>