除了指示網(wǎng)頁(yè)文檔元素的選擇器外,還有另外兩種類型的選擇器:類選擇器(class selector)和ID選擇器(ID selector),它們?cè)试S以一種獨(dú)立于文檔元素的方式來指定樣式。這些選擇器可以單獨(dú)使用,也可以與其他元素選擇器結(jié)合使用。不過,只有適當(dāng)?shù)貥?biāo)記文檔后才能使用這些選擇器,所以使用這兩種選擇器通常需要先做一些構(gòu)想和計(jì)劃。
例如,假設(shè)你在制作一個(gè)網(wǎng)頁(yè),討論钚的各種處理方法。這個(gè)網(wǎng)頁(yè)中對(duì)于如何安全地處理這樣一種危險(xiǎn)物質(zhì)有很多警告。你希望這些警告以粗體文本出現(xiàn),這樣就能突出顯示。不過,你并不知道這些警告具體是哪些元素。有些警告可能是整個(gè)段落,而另外一些可能只是一個(gè)長(zhǎng)長(zhǎng)的列表中的一項(xiàng),或者只是一小段文本。所以,無法使用任何簡(jiǎn)單選擇器來定義這樣一個(gè)規(guī)則。假設(shè)你想把規(guī)則寫作:
p {font-weight: bold;}
那么所有段落都會(huì)變成粗體,而不僅是那些包含警告的段落。你需要一種合適的方法,只選擇包含有警告的文本,或者更確切地講,需要一種方法只選擇作為警告的那些元素。該怎么做呢?這種情況下可以使用類選擇器,向文檔中已經(jīng)以某種方式標(biāo)記的部分應(yīng)用樣式,而不考慮具體涉及到哪些元素。
要應(yīng)用樣式而不考慮具體涉及的元素,最常用的方法就是使用類選擇器。不過,在使用類選擇器之前,需要修改具體的文檔標(biāo)記,以便類選擇器正常工作。輸入以下class屬性:
<p class="warning">When handling plutonium,care must be taken to avoid the formation of a critical mass.</p>
<p>With plutonium,<span class="warning">the possibility of implosion is very real, and must be avoided at all costs</span> This can be accomplished by keeping the various masses separate.</p>
為了將一個(gè)類選擇器的樣式與元素關(guān)聯(lián),必須將class屬性指定為一個(gè)適當(dāng)?shù)闹?。在前面的代碼中,有兩個(gè)元素的class值指定為warning:第一段(第一個(gè)p元素)以及第二段中的span元素。
現(xiàn)在所需要的僅是向這些歸類的元素應(yīng)用樣式的方法。對(duì)于HTML文檔,可以使用一種很簡(jiǎn)潔的記法,即類名前有一個(gè)點(diǎn)號(hào)(.),而且可以結(jié)合一個(gè)簡(jiǎn)單選擇器:
*warning {font-weight:bold;}
也就是說,font-weight: bold的網(wǎng)頁(yè)樣式會(huì)應(yīng)用到class屬性值為warning的所有元素(因?yàn)檫@里有一個(gè)通配選擇器)。
可以看到,類選擇器要正常工作,需要直接引用一個(gè)元素的class屬性中的值。這個(gè)引用前面往往有一個(gè)點(diǎn)號(hào)(.),標(biāo)記這是一個(gè)類選擇器。通過這個(gè)點(diǎn)號(hào),可以幫助類選擇器與它可能結(jié)合的其他部分分隔開(如類選擇器可能結(jié)合了元素選擇器)。例如,你可能希望只在整個(gè)段落是警告時(shí)才顯示為粗體文本:
p.warning {font-weight: bold;}
選擇器現(xiàn)在會(huì)匹配class屬性包含warning的所有p元素,但是其他任何類型的元素都不匹配,不論是否有此class屬性。選擇器p.warning解釋為:“其class屬性包含詞warning的所有段落?!币?yàn)閟pan元素不是一個(gè)段落,這個(gè)規(guī)則的選擇器與之不匹配,因此span元素不會(huì)變成粗體文本。
如果你確實(shí)希望為span元素指定不同的樣式,可以使用選擇器span.warning:
p.warning {font-weight: bold;}
span.warning {font-style: italic;}
在這種情況下,警告段落會(huì)變成粗體,而警告span會(huì)變成斜體。每個(gè)規(guī)則只應(yīng)用于某種特定類型的元素/類組合,所以不會(huì)影響其他元素。
另一種選擇是組合使用一個(gè)通用類選擇器和一個(gè)元素特定類選擇器,這樣可以得到更有用的樣式,如以下標(biāo)記所示:
.warning {font-style: italic;}
span.warning {font-weight: bold;}
在這種情況下,所有警告文本都會(huì)變成斜體,不過只有class為warning的span元素中的文本會(huì)變?yōu)榇中斌w。
注意前例中通用類選擇器的格式:這里只有一個(gè)類名,前面有一個(gè)點(diǎn)號(hào)而沒有任何元素名。如果你只想選擇所有類名相同的元素,可以在類選擇器中忽略通配選擇器,這沒有任何不好的影響。
我們處理了class值中包含一個(gè)詞的情況。在網(wǎng)頁(yè)中,一個(gè)class值中有可能包含一個(gè)詞列表,各個(gè)詞之間用空格分隔。例如,如果希望將一個(gè)特定的元素同時(shí)標(biāo)記為緊急(urgent)和警告(warning),就可以寫作:
<p class="urgent warning">When handling plutonium, care must be taken to avoid the formation of a critical mass.</p>
<p>With plutonium,<span class="warning">the possibility of implosion is very real, and must be avoided at all costs</span>. This can be acconplished by keeping the various masses separate.</p>
這兩個(gè)詞的順序無關(guān)緊要,寫成warning urgent也可以。
現(xiàn)在假設(shè)希望class為warning的所有元素都是粗體,而class為urgent的所有元素為斜體,class中同時(shí)包含warning和urgent的所有元素還有一個(gè)銀色的背景。就可以寫作:
.warning {font-weight: bold;}
.urgent {font-style: italic;}
.warning.urgent {background: silver;}
通過把兩個(gè)類選擇器鏈接在一起,僅可以選擇同時(shí)包含這些類名的元素(類名的順序不限)??梢钥吹剑W(wǎng)頁(yè)源代碼中包含class="urgent warning",但CSS選擇器寫作.warning .urgent。不過,這個(gè)規(guī)則還是會(huì)導(dǎo)致“When handling plutonium ...”段落有一個(gè)銀色的背景。
如果一個(gè)多類選擇器包含類名列表(類名以空格分隔)中所沒有的一個(gè)類名,匹配就會(huì)失敗。考慮以下規(guī)則:
p.warning.help {background: red;}
不出所料,這個(gè)選擇器將只匹配class包含詞warning和help的那些p元素。因此,如果一個(gè)P元素的class屬性中只有詞warning和urgent,將不能匹記。不過,它能匹配以下元素:
<p class="urgent warning help">Help me!</p>
警告:在IE7之前的版本中,不同平臺(tái)的Internet Explorer都不能正確地處理多類選擇器。對(duì)于這些較早的版本,盡管可以選擇列表中的一個(gè)類名,但是要根據(jù)列表中的多個(gè)類名進(jìn)行選擇時(shí)則無法工作。因此,P.waming可以正常工作,但p.warning.help會(huì)匹配class屬性中包含help的所有p元素,因?yàn)閔elp在選擇器中最后出現(xiàn)。如果寫作p.help.warning,較老版本的Explorer就會(huì)匹配class值中包含warning的所有p元素,而不論其中是否出現(xiàn)help。
在某些方面,ID選擇器類似于類選擇器,不過也有一些重要的差別。首先,ID選擇器前面有一個(gè)#號(hào)——也稱為棋盤號(hào)而不是點(diǎn)號(hào)。因此,可以看到如下的一個(gè)規(guī)則:
*#first-para {font-weight: bold;}
這個(gè)規(guī)則會(huì)讓id屬性中包含值first-para的所有元素顯示為粗體文本。
第二個(gè)區(qū)別是ID選擇器不引用class屬性的值,毫無疑問,它要引用id屬性中的值,以下是一個(gè)實(shí)標(biāo)ID選擇器的例子:
*#lead-para {font-weight:bold;}
<p id="lead-para">This paragraph will be boldfaced.</p>
<p>This paragraph will NOT be bold.</p>
注意可能對(duì)文檔中的任何元素指定了值lead-para。在這個(gè)特定情況下,規(guī)則將應(yīng)用到第一段,不過也可以同樣很容易地應(yīng)用到第二段或第三段。
與類選擇器一樣,ID選擇器中可以忽略通配選擇器。前面的例子也可以寫作:
#lead-para {font-weighc:bold;}
這個(gè)選擇器的效果將是一樣的。
如前所述,可以為任意多個(gè)元素指定類,前例中類名warning被應(yīng)用到p和span元素,而且它還可以應(yīng)用到更多的元素。與此不同,在一個(gè)HTML文檔中,ID選擇器會(huì)使用一次,而且僅一次。因此,如果有一個(gè)元素的id值為lead-para,那么該文檔中所有其他元素的id值都不能是lead-para。
注意:實(shí)際中,瀏覽器通常并不檢查網(wǎng)頁(yè)中ID的唯一性,這意味著如果你在HTML文檔中設(shè)罝了多個(gè)有相同ID屬性值的元素,就可能為這些元素應(yīng)用相同的樣式。這種行為是不正確的,不過這種情況常會(huì)發(fā)生。如果一個(gè)文檔中有多個(gè)相同的ID值,還會(huì)導(dǎo)致編寫DOM腳本更為困難,因?yàn)橄駁etElementByid( )之類的函數(shù)的前提是僅一個(gè)元素有給定的ID值。
不同于類選擇器,ID選擇器不能結(jié)合使用,因?yàn)镮D屬性不允許有以空格分隔的詞列表。
從純語法意義上講,點(diǎn)號(hào)加類名的記法(如.warning)對(duì)XML文檔不一定能奏效。在寫這本書時(shí),點(diǎn)號(hào)加類名的記法在HTML、SVG和MathML中能正常工作,也許將來的語言也支持,不過這要由各個(gè)語言的規(guī)范來決定。#號(hào)加ID的記法(如#Lead)可以在任何文檔語言中使用,只要其中有一個(gè)屬性在文檔中能保證唯一即可。唯一性可以用名為id的屬性來保證,或者可以是任何其他屬性,只要屬性的內(nèi)容在文檔中定義為唯一。
class名和id名之間的另一個(gè)區(qū)別是,如果你想確定應(yīng)當(dāng)向一個(gè)給定元素應(yīng)用哪些樣式,ID能包含更多含義。
類似于類,還可以獨(dú)立于元素來選擇ID。有些情況下,你知道文檔中會(huì)出現(xiàn)某個(gè)特定的ID值,但是并不知道它會(huì)出現(xiàn)在哪個(gè)元素上(就像處理钚的警告一樣),所以你想聲明獨(dú)立的ID選擇器。例如,你可能知道在一個(gè)給定的文檔中會(huì)有一個(gè)ID值為most important的元素。你不知道這個(gè)最重要的東西是一個(gè)段落、一個(gè)短語、一個(gè)列表項(xiàng)還是一個(gè)小節(jié)標(biāo)題。你只知道每個(gè)文檔中都會(huì)有這么一個(gè)最重要的內(nèi)容,它可能出現(xiàn)在任何元素中,而且只能出現(xiàn)一次。在這種情況下,可以編寫如下規(guī)則:
#mostImportant {color: red; background: yellow;}
這個(gè)規(guī)則會(huì)與以下各個(gè)元素匹配(前面已經(jīng)提到,這些元素不能在同一個(gè)文檔中同時(shí)出現(xiàn),因?yàn)樗鼈兌加邢嗤腎D值):
<h1 id="mostImportant ">This is important!</h1>
<em id="mostImportant ">This is important!</em>
<ul id="mostlmportant">This is important!</ul>
還要注意,類選擇器和ID選擇器是區(qū)分大小寫的,這取決于網(wǎng)頁(yè)語言。HTML和XHTML將類和ID值定義為區(qū)分大小寫,所以類和ID值的大小寫必須與文檔中的相應(yīng)值匹配。因此,對(duì)于以下的CSS和HTML,元素不會(huì)變成粗體:
p.criticalInfo {font-weight:bold;}
<p class="criticalinfo">Don't look down.</p>
由于字母i的大小寫不同,所以選擇器不會(huì)匹配以上元素。
警告:一些較老的瀏覽器不區(qū)分類名和ID名的大小寫,但是寫這本書時(shí),所有當(dāng)前的瀏覽器都要求區(qū)分大小寫。
對(duì)于類選擇器和ID選擇器,你所做的實(shí)際上只是選擇屬性值。前面兩小節(jié)中使用的語法是HTML、SVG和MathML文檔特定的(寫這本書時(shí)是如此),在其他標(biāo)記語言中,不能使用這些類和ID選擇器。為了解決這個(gè)問題,CSS2引人了屬性選擇器(attribute selector),它可以根據(jù)元素的屬性及屬性值來選擇元素。共有4種類型的屬性選擇器。
警告:Safari、Opera和所有基于Gecko的瀏覽器都支持屬性選擇器,不過在IE5/Mac和IE6/Win 之前,Internet Explorer并不支持屬性選擇器。IE7全面支持所有CSS2.1屬性選擇器,還支持一些CSS3屬性選擇器,這一節(jié)將討論這個(gè)內(nèi)容。
簡(jiǎn)單屬性選擇
如果希望選擇有某個(gè)屬性的元素,而不論該屬性的值是什么,可以使用一個(gè)簡(jiǎn)單屬性選擇器。例如,要選擇有class屬性(值不限)的所有h1元素,使其文本為銀色,可以寫作:
h1[class]{color: silver;}
所以,給定如下標(biāo)記:
<h1 class="hoopla">Hello</h1>
<h1 class="severe">Serenity</h1>
<h1 class="fancy">Foo1ing</h1>
這個(gè)策略在XML文檔中相當(dāng)有用,因?yàn)閄ML語言主張要針對(duì)元素和屬性的用途指定元素名和屬性名。考慮描述太陽(yáng)系行星的一個(gè)XML語言(我們稱之為PlanetML)。如果你想選擇有moons屬性的所有planet元素,使之顯示為粗體,以便能更關(guān)注有moons的行星,就可以寫作:
planet[moons]{font-weight: bold;}
這會(huì)讓以下標(biāo)記片段中第二個(gè)和第三個(gè)元素的文本顯示為粗體,但第一個(gè)元素的文本不是粗體:
<planet>Venus</planet>
<planet moons="1">Earth</planet>
<planet moons="2">Mars</planet>
在網(wǎng)頁(yè)文檔中,可以采用一些創(chuàng)造性的方法使用這個(gè)特性。例如,可以對(duì)所有帶有alt屬性的圖像應(yīng)用某種樣式,從而突出顯示這些有效的圖像:
img[alt](border: 3px solid red;}
(這個(gè)特例更適合用來診斷而不是設(shè)計(jì),即用來確定圖像是否確實(shí)有效。)
如果你想把包含標(biāo)題(title)信息的所有元素變?yōu)榇煮w顯示(光標(biāo)停留在這些元素上時(shí)大多數(shù)瀏覽器都會(huì)將其顯示為“工具提示”),就可以寫作:
*[title]{font-weight: bold;}
類似地,可以只對(duì)有href屬性的錨(a元素)應(yīng)用樣式。
還可以根據(jù)多個(gè)屬性進(jìn)行選擇,只需將屬性選擇器鏈接在一起即可。例如,為了將同時(shí)有href和title屬性的網(wǎng)頁(yè)超鏈接的文本置為粗體,可以寫作:
a[href][title]{font-weight: bold;}
這會(huì)將以下標(biāo)記中的第一個(gè)鏈接變成粗體,但第二個(gè)和第三個(gè)鏈接不變:
<a hre£="htcp://ww.w3.org/" title="W3C Home">W3C</a><br />
<a href ="http://www.webstandards.org">Standards Info</a><br />
<a title="Not a link">dead letter</a>
除了選擇有某些屬性的元素,還可以進(jìn)一步縮小選擇范圍,只選擇有特定屬性值的元素。例如,假設(shè)想將指向網(wǎng)站上某個(gè)特定文檔的超鏈接變成粗體,可以寫作:
a[href="http:www.css-discuss.org/about.html"]{font-weight: bold;}
可以為任何元素指定屬性和值組合。不過,如果文檔中沒有出現(xiàn)該組合,選擇器將無法匹配。同樣地,XML語言也可以利用這種方法來設(shè)置樣式。下面再回到我們的PlanetML例子。假設(shè)只想選擇moons屬性值為1的那些planet元素:
planet[moons="1"]{font-weight: bold;}
這會(huì)把以下標(biāo)記片段中第二個(gè)元素的文本變成粗體,但第一個(gè)和第三個(gè)元素不受影響:
<planet>Venus</planet>
<planet moons="1">Eareh</planet>
<planet moons="2">Mars</planet>
與屬性選擇類似,可以把多個(gè)屬性-值選擇器鏈接在一起來選擇一個(gè)文檔。例如,為了將href值為http://www.w3.org/而且title屬性值為W3C Home的所有HTML超鏈接的文本大小加倍,可以寫作:
a[href="http://www.w3.org/"][title="W3C Home"]{font-size: 200%;}
這會(huì)把以下標(biāo)記中第一個(gè)鏈接的文本大小加倍,但第二個(gè)或第三個(gè)鏈接不受影響:
<a href="http://www.w3 .org/" title="W3C Home">W3C</a><br />
<a href="http://www.webstandards.org" title="Web Standards Organization">Standards Info</a><br />
<a href="http://www.example.org/" title="W3C Home">dead.link</a>
注意,這種格式要求必須與屬性值完全匹配。如果遇到的值本身包含一個(gè)用空格分隔的值列表(如HTML屬性class),匹配就會(huì)出問題。例如??紤]以下標(biāo)記片段:
<planet type="barren rocky">Mercury</planet>
要根據(jù)具體屬性值匹配這個(gè)元素,唯一的辦法就是寫作:
planet[type="barren rocky"]{font-weight:bold;}
如果寫成planet[type="barren"],這個(gè)規(guī)則不能匹配示例標(biāo)記,因而會(huì)失敗。HTML中的class屬性也是如此??紤]以下片段:
<p class="urgent warning">When handling plutonium, care must be taken to avoid the formation of a critical mass.</p>
要根據(jù)具體屬性值來選擇這個(gè)元素,必須寫作:
p[class="urgent warning"]{font-weight: bold;}
這不同于先前介紹的點(diǎn)號(hào)類名記法,有關(guān)內(nèi)容將在下一節(jié)討論。相反,這個(gè)規(guī)則會(huì)選擇class屬性值為urgent warning的所有p元素,要求屬性值中urgent在前warning 在后,而且有一個(gè)空格將其分隔,這實(shí)際上就是一個(gè)完全串匹配。
另外,要注意ID選擇器與指定id屬性的屬性選擇器不是一回事。換句話說,h1#page-title和h1[id="page-title"]之間存在著微妙但很重要的差別。
如果屬性能接受詞列表(詞之間用空格分隔),可以根據(jù)其中的任意一個(gè)詞進(jìn)行選擇。在HTML中,這方面最經(jīng)典的例子就是class屬性,它能接受一個(gè)或多個(gè)詞作為其屬性值。以下是我們經(jīng)常使用的示例文本:
<p class="urgent warning">When handling plutonium, care must be taken to avoid the formation of a critical mass.</p>
假設(shè)你想選擇class屬性中包含warning的元素,可以用一個(gè)屬性選擇器做到這一點(diǎn):
p[class~="warning"]{font-weight:bold;}
注意選擇器中出現(xiàn)了一個(gè)波浪號(hào)(~)。這正是部分選擇的關(guān)鍵,即根據(jù)屬性值中出現(xiàn)的一個(gè)用空格分隔的詞來完成選擇。如果忽略了這個(gè)波浪號(hào),如上一節(jié)所述,則說明需要完成完全值匹配。這個(gè)選擇器構(gòu)造等價(jià)于先前討論的點(diǎn)號(hào)類名記法。因此,p.warning和p[class~="warning"]應(yīng)用到HTML文檔時(shí)是等價(jià)的。以下是一個(gè)例子,這是前面“PlanetML”標(biāo)記的網(wǎng)頁(yè)版本:
<span class="barren rocky">Mercury</planet>
<span class="cloudy barren">Venus</planet>
<span class="life-bearing cloudy">Earth</planet>
為了把class屬性中有barren的所有元素變?yōu)樾斌w,可以寫作:
span[class~="barren"]{font-style: italic;}
這個(gè)規(guī)則的選擇器會(huì)匹配示例標(biāo)記中的前兩個(gè)元素,因此這兩個(gè)元素的文本將變成斜體。寫作span.barren {font-style:italic;}也能得到同樣的結(jié)果。
那么HTML中為什么還要有這種“~=”屬性選擇器呢?因?yàn)樗苡糜谌魏螌傩?,而不只是class。例如,可以有一個(gè)包含大量圖像的文檔,其中只有一部分是圖片。對(duì)此,可以使用一個(gè)基于title文本的部分值屬性選擇器,只選擇這些圖片。
img[title~="Figure"]{border: 1px solid gray;}
這個(gè)規(guī)則會(huì)選擇title文本包含F(xiàn)igure的所有圖像。因此,只要圖片有諸如“Figure 4. A bald-headed elder statesman"之類的title文本,就能與這個(gè)規(guī)則匹配。由于這個(gè)原因,選擇器img[title~="Figure"]還會(huì)匹配值為“How To Figure Out Who's In Charge”的title屬性。沒有title屬性的圖像或者title值中不包含“Figure”的圖像都不會(huì)匹配。
還有一個(gè)更高級(jí)的CSS選擇器模塊,這是在CSS2完成之后發(fā)布的,其中包含更多的部分值屬性選擇器(或者按規(guī)范的說法,稱之為“子串匹配屬性選擇器”)。由于這些屬性選擇器在很多現(xiàn)代瀏覽器中都得到了支持,包括IE7。
理解這個(gè)結(jié)構(gòu)模型后,第一個(gè)好處是可以定義后代選擇器(descendant selector,也稱為包含選擇器)或上下文選擇器(contextual selector)。定義后代選擇器就是來創(chuàng)建一些規(guī)則,它們僅在某些結(jié)構(gòu)中起作用,而在另外一些結(jié)構(gòu)中不起作用。舉例來說,假設(shè)你希望只對(duì)從h1元素繼承的那些em元素應(yīng)用樣式??梢栽趆1中找到的每個(gè)em元素上放一個(gè)class屬性,但是這就像使用font標(biāo)記一樣費(fèi)功夫。顯然,更高效的做法是聲明一些規(guī)則,只與h1元素中包含的em元素匹配。
為此,可以寫作:
h1 em {color: gray;}
這個(gè)規(guī)則會(huì)把作為h1元素后代的em元素的文本變成灰色。其他em文本(如段落或塊引用中的em)則不會(huì)被這個(gè)規(guī)則選中。
在一個(gè)后代選擇器中,規(guī)則左邊的選擇器一端包括兩個(gè)或多個(gè)用空格分隔的選擇器。選擇器之間的空格是一種結(jié)合符(combinator)。每個(gè)空格結(jié)合符可以解釋為“……在……中找到”,“……作為……的一部分”,或“……作為……的后代”,但是要求必須從右向左讀選擇器。因此,h1 em可以解釋為“作為h1元素后代的任何em元素”(譯注1)[1]。(如果要從左向右讀選擇器,可以換成以下說法:“包含一個(gè)em的所有h1會(huì)把以下樣式應(yīng)用到該em”)
當(dāng)然并不僅限于兩個(gè)選擇器,例如:
在這種情況下,會(huì)把一個(gè)無序列表中的強(qiáng)調(diào)文本置為灰色,這個(gè)無序列表是一個(gè)有序列表的一部分,而這個(gè)有序列表本身又是另一個(gè)無序列表的一部分(盡管很復(fù)雜,不過這確實(shí)沒有錯(cuò))。顯然這是一個(gè)很特定的選擇原則。
后代選擇器功能極其強(qiáng)大。有了這些后代選擇器,使得網(wǎng)頁(yè)中不可能實(shí)現(xiàn)的任務(wù)(至少是如果不大量使用font標(biāo)記就無法做到的事情)成為可能。假設(shè)有一個(gè)文檔,其中有一個(gè)邊欄,還有一個(gè)主區(qū)。邊欄的背景為藍(lán)色,主區(qū)背景為白色,這兩個(gè)區(qū)都包含鏈接列表。
不能把所有這些鏈接都設(shè)置為藍(lán)色,因?yàn)檫@樣一來邊欄中的藍(lán)色鏈接將無法看到。
解決方法是使用后代選擇器。在這種情況下,可以為包含邊欄的表單元格指定一個(gè)值為sidebar的class屬性,并把主區(qū)的class屬性值設(shè)置為main。然后編寫以下樣式:
td.sidebar {background: blue;}
td.main {background: white;}
td.sidebar a:link {color: white;}
td.main a:link {color: blue;}
注意:link指示尚未訪問的資源的鏈接。
下面是另一個(gè)例子:假設(shè)你希望blockquote中包含的所有b(粗體)元素的文本顏色為灰色,另外正常段落中的所有粗體文本也為灰色:
blockquote b, p b {color: gray;}
其結(jié)果是,作為段落或塊引用后代的b元素中的文本會(huì)變成灰色。
關(guān)于后代選擇器有一個(gè)常被忽視的方面,即兩個(gè)元素之間的層次間隔可以是無限的。例如,如果寫作ul em,這種語法就會(huì)選擇從ul元素繼承的所有em元素,而不論em的嵌套層次多深。因此,ul em將會(huì)選擇以下標(biāo)記中的em元素:
<ol>
<li>List item 1
<li>List item 1-1</li>
<li>List item 1-2</li>
<li>List item 1-3
<ol>
<li>List item 1-3-1</li>
<li>List item <em>l-3-2</em></li>
<li>List item l-3-3</li>
</ol></li>
<li>List item 1-4</li>
</ol></li>
</ul>
在某些情況下,可能并不想選擇一個(gè)任意的后代元素:而是希望縮小范圍,只選擇另一個(gè)元素的子元素。例如,你可能想選擇只作為一個(gè)h1元素子元素(而不是后代元素)的 strong元素。為此,可以使用子結(jié)合符,即大于號(hào)(>):
h1>strong {color: red;}
這個(gè)規(guī)則會(huì)把第一個(gè)h1下面出現(xiàn)的strong元素變成紅色,但是第二個(gè)出現(xiàn)的strong 元素不受影響。
<h1>This is <strong>very</strong> important.</<h1>
<h1>This is <em>really <strong>very</strong></em> important.<h1>
如果從右向左讀(譯注2)[2],選擇器h1 > strong可以解釋為“選擇作為h1元素子元素的所有strong元素”。子結(jié)合符兩邊可以有空白符,這是可選的。因此,h1 > strong,h1> strong和 h1>strong都是一樣的,只要你愿意,可以使用空白符,也可以忽略空白符,
查看文檔的樹結(jié)構(gòu)時(shí),可以很容易地看到,子選擇器限制為只匹配樹中直接相連的元素。
在這個(gè)樹片段中,可以很容易地看出父子關(guān)系。例如,a元素是strong元素的父元素,但是它又是p元素的子元素??梢杂胮> a和 a>strong選擇器來匹配這個(gè)片段中的元素,但是p> strong不行,因?yàn)閟trong是p的后代而不是其子元素。
還可以在同一個(gè)選擇器中結(jié)合使用后代選擇器和子選擇器。因此,table.suitimary td > P會(huì)選擇作為一個(gè)td元素子元素的所有p元素,這個(gè)td元素本身從table元素繼承,該table元素有一個(gè)包含summary的class屬性。
假設(shè)你希望對(duì)一個(gè)標(biāo)題后緊接著的段落應(yīng)用樣式,或者向一個(gè)段落后緊接著的列表指定特殊的外邊距。要選擇緊接在另一個(gè)元素后的元素,而且二者有相同的父元素,可以使用相鄰兄弟結(jié)合符(adjacentsibling combinator),這表示為一個(gè)加號(hào)(+)。與子結(jié)合符一樣,相鄰兄弟結(jié)合符旁邊可以有空白符,這要看創(chuàng)作人員的喜好。
要去除緊接在一個(gè)h1元素后出現(xiàn)的段落的上邊距,可以寫作:
h1 + p {margin-top: 0;}這個(gè)選擇器讀作“選擇緊接在一個(gè)h1元素后出現(xiàn)的所有段落。h1要與p元素有共同的父元素”。
為了形象地展示這個(gè)選擇器是如何工作的,最容易的辦法是再來考慮一個(gè)文檔樹的片段。
在這個(gè)片段中,div元素中包含兩個(gè)列表,一個(gè)是有序列表,另一個(gè)是無序列表,每個(gè)列表都包含三個(gè)列表項(xiàng)。這兩個(gè)列表是相鄰兄弟,列表項(xiàng)本身也是相鄰兄弟。不過,第一個(gè)列表中的列表項(xiàng)不是第二個(gè)列表中列表項(xiàng)的兄弟,因?yàn)檫@兩組列表項(xiàng)的父元素不同(最多只能算堂兄弟)。
要記住,用一個(gè)結(jié)合符只能選擇兩個(gè)相鄰兄弟中的第二個(gè)元素。因此,如果寫作li+li {font-weight: bold;},只會(huì)把各列表中的第二個(gè)和第三個(gè)列表項(xiàng)變成粗體。第一個(gè)列表項(xiàng)將不受影響。
要想網(wǎng)頁(yè)正常地工作,CSS要求兩個(gè)元素按“源順序”出現(xiàn)。在前面的例子中,ol元素后面有一個(gè)ul元素。因此可以用ol+ul選擇第二個(gè)元素,但是用這個(gè)語法無法選擇第一個(gè)元素。要想與ul+ol匹配有序列表必須緊跟在無序列表后面。
另外,兩個(gè)元素之間的文本內(nèi)容不會(huì)影響相鄰兄弟結(jié)合符起作用。考慮以下標(biāo)記片段,其樹視圖與圖2-19相同:
<div>
<ol>
<li>List item 1</li>
<li>List item 1</li>
<li>List item 1</li>
</ol> This is some text that is part of the 'div'.
<ul>
<li>A list item</li>
<li>Another list item</li>
<li>Yet another list item</li>
</ul>
</div>
盡管兩個(gè)列表間多了一行文本,不過還是可以用選擇器ol+ul來匹配第二個(gè)列表。這是因?yàn)椋虚g的文本并不包含在兄弟元素中,而只是父元素div的一部分。如果將這個(gè)文
l+p + ul。
如以下示例所示,相鄰兄弟結(jié)合符還可以結(jié)合其他結(jié)合符:
html > body table + ul{margin-top: 1.5em;}
這個(gè)選擇器解釋為“選擇緊接在一個(gè)table元素后出現(xiàn)的所有兄弟ul元素,該table 元素包含在一個(gè)body元素中,body元素本身是html元素的子元素”。
警告:Windows平臺(tái)的Internet Explorer在IE6之前不支持子選擇器和相鄰兄弟選擇器。IE7對(duì)二者則提供了支持。