HTML文檔是一棵樹的結構,各元素以一種階層為基礎構成‘樹’的視圖。文檔樹中的每個元素,要麼是另一個元素的父元素,要麼是另一個元素的子項目,這樣,各元素之間就形成了‘父子關係’。基於這樣的關聯式模式,CSS定義了後代選取器(descendant selector)也稱為上下文選取器(contextual selector)。
後代選取器的寫法為,子代元素以空格與父元素形成串連關係構成選取器,如:
div span{color:blue;}
以上規則的結果為:“作為div元素後代的任何span元素顯示為藍色字型”。
選取器之間的空格是一種結合符(combinator)。每個空格結合符可以解釋為“...在...中找到”、“...作為...的一部分”、“...作為...的後代”,但是要求必須從右向左讀選取器——《CSS權威指南》第三版
CSS還有兩種選取器:類別選取器和ID選取器,個中細則不是本文陳述的重點。本文的重點是:空格在後代選取器、類別選取器和ID選取器相結合的情況中的種種問題,及解決方式。
先看看以下的規則:
div.blue {color:blue;}
以上規則的結果為:“所有class屬性值為blue的div元素顯示為藍色字型”。然而我的要求並不是這樣,我的要求是:“作為div元素後代的任何class屬性值為blue的元素顯示為藍色字型”。試試以下的規則:
div .blue{color:blue;}
以上規則的改進之處為'div'與'.blue'之間多了一個空格,這樣是否就能形成後代選取器呢?答案是否定的!該規則實現的結果依舊是:“所有class屬性值為blue的div元素顯示為藍色字型”。
那麼該怎麼結合類別選取器構成後代選取器的效果呢?方法是有的,那就是給父元素div設定一個class或者id屬性,假設我給它加上一個class屬性,於是規則就變為:
div.contain .blue{color:blue;}
以上規則的結果為:“所有class屬性值為contain的div元素,其後代中class屬性值為blue的任何元素顯示為藍色字型”。結果雖然不能完全達到我的苛刻要求,但已經很接近了。接近了,效果一定是很明顯的,然而我卻發現完全沒有了藍色字型,因為我把規則寫為:
div.contain.blue{color:blue;}
以上規則的不同之處在於,'.contain'與'.blue'之間少了一個空格!少了空格,以上選取器就不是後代選取器了,而是另外一種選取器:“多類別選取器”。
在HTML中,一個class值中有可能包含一個詞列表,各個詞之間用空格分隔。那麼以上的多類別選取器只能將規則應用於如下形式的元素中:
<div class="contain blue">text</div>
以上的class屬性值少了其中一個都無法將字型顯示為藍色!
將以上規則放在一起,比較起來會清晰一點:
1 div.contain .blue{color:blue;}/*後代選取器*/
2 div.contain.blue{color:blue;} /*多類別選取器*/
以上兩種規則分別應用的元素如下:
1 <div class="contain">contain<span class="blue">blue</span><!--後代-->
2 <div class="contain blue">contain and blue</div><!--多類-->
值得注意的是:ID屬性不允許有以空格分隔的詞列表。所以以下的規則將無法應用到任何元素:
div#contain#blue{color:blue;}
以上的規則將無法應用到任何元素。你只能乖乖地用空格將兩個ID選取器分隔,構成後代選取器。
綜上,選取器之間的空格是一種結合符,如果要構成後代選取器,則空格兩邊的選擇符必須為如下兩種形式:
- 元素選擇符 空格 元素選擇符
- 非元素選擇符 空格 非元素選擇符
後代選取器中絕對不可能出現的一種情形:元素選擇符 [空格] 非元素選擇符。
最重要一點:兩個類別選取器之間存在空格則構成後代選取器,之間沒有空格的則構成多類別選取器。
參考資料:《CSS權威指南:第三版》Eric A.Meyer著 尹志忠 侯妍譯