1. 程式人生 > >CSS 篩選器詳解

CSS 篩選器詳解

1.為什麼要研究CSS篩選器?因為想在頁面中控制一個元素的樣式太困難太麻煩了。使用內聯CSS基本上宣佈了放棄介面的可維護性;使用js修改樣式,寫不好的話,維護性也等同於零。而CSS樣式表是原生的維護性最好的外掛,好的樣式表,可以控制整站樣式。更關鍵的是,jQuery也使用CSS篩選器來抓取DOM引用。因此,CSS篩選器,是前端攻城屍必修課之一。

2.什麼是篩選器?篩選器,翻譯成普通話,就是一個或一組判斷條件。頁面中有不計其數的DOM,這些DOM之間的關係又非常複雜,篩選器的目的,就是找到某個或某類符合條件的DOM,方便其他程式對這些DOM進行修改。因此,篩選器應該能描述兩種資訊:一是要尋找的DOM的特性,而是要尋找的DOM與其他DOM的關係。

3.篩選器的分類。CSS中一共有四種篩選器(這是我自己分的),從四個角度描述DOM的特定:
    (1)元素篩選器:p {styles...}、h2 {styles...}、* {styles...}
        直接用html標籤名稱進行篩選,如p表示所有段落、h2表示所有二級標題。這裡有一個特殊標籤就是*,表示所有。元素篩選器規定的樣式,會應用到所有元素,因此只在這裡設定諸如字型、字號一類的通用樣式。
    (2)類篩選器:.className1
{styles...}
        這是針對含有class屬性的標籤而言的。html標籤中規定了class屬性,對應的類篩選器就會把這些DOM找到。類篩選器和元素篩選器一樣,都是多元素篩選,即有多個DOM的class都設定成className,那麼這些DOM的樣式都會被改變。我本人不太喜歡類篩選器,因為在html中新增class也是意見很麻煩的事。
    (3)ID篩選器:#idString {styles...}
        ID篩選器用法和類篩選器很類似。但篩選的目標從class屬性變成了id屬性。不同在於,類篩選器會找出所有滿足條件的DOM,而ID篩選器只找出第一個符合條件的DOM。因此,在html中把兩個標籤的id設定成一個值,第二個標籤的id屬性等於沒用。
    (4)屬性篩選器:[attr=value] {styles...}
        屬性篩選器和類篩選器一樣,也是多DOM選擇,但又更泛化了,可以通過這個篩選一些自定義屬性或者比較奇怪的屬性,比如href、src。屬性篩選器更強大的是,對value的匹配,有好幾個運算子:
                        
[attr]用於選取帶有指定屬性的元素。
                        [attr = value]用於選取帶有指定屬性和值的元素。 [attr ~= value] 用於選取屬性值中包含指定詞彙的元素(基本等同於*)。 [attr |= value] 用於選取帶有以指定值開頭的屬性值的元素,該值必須是整個單詞(基本等同於^)。 [attr ^= value] 匹配屬性值以指定值開頭的每個元素(常用)。 [attr $= value] 匹配屬性值以指定值結尾的每個元素(常用)
[attr *= value] 匹配屬性值中包含指定值的每個元素(常用)

4.篩選器的組合。CSS中一共有五種篩選器組合方式,從五個角度描述待尋找DOM與其他DOM之間的關係。
    (1)逗號組合:h1, h2, h3 {styles...}
        逗號組合描述了一種並集的關係,即當前元素,滿足任何一個篩選器,就應用樣式。比如上面的例子,如果當前標籤是h1、h2、h3中任意一種,那麼應用樣式。
    (2)無間斷組合:div.className1 {styles...}
        一個以上篩選器(一般是不同型別的篩選器),直接連在一起,中間沒有任何分隔符。 這表示一種交集的關係,即當前元素,必須滿足所有篩選器,才能被應用樣式。比如上面的例子,如果當前元素是div標籤,並且class屬性為className1,那麼應用樣式。
    (3)空格組合:div .className1 {stlyes...}(注意與上面的區別,div後面有一個空格)
        一個以上篩選器(類別無所謂),之間存在空格。這表示一種孩子關係,空格前面的是父親、空格後面是孩子。意思是先找出父親,然後在父親內部找出孩子。 比如上面的例子,篩選過程是先找到div標籤A,然後在A的內部找class等於className1的標籤B,然後對標籤B使用樣式。注意,不對A進行樣式修改,只對B進行修改,另外B未必是A的直接孩子,B只要在A的內部即可。
        這種組合是非常非常常用的。也是我不喜歡類篩選器的原因。
    (4)直接孩子組合:div > .className1 {styles...}
        在空格組合中,細心的朋友可能已經注意到了,只要B在A的內部,那麼就會被篩選出來。這樣是否太寬泛了點,篩選的內容是否會多了點。很多時候,我們只需要找出直接孩子,而不希望找出孩子的孩子。比如:
<style>
	div p {color:#f00;}<!--樣式A-->
</style>
<div>
	<p>title1</p>
	<table>
	<tr><td>
		<p>title2</p>
		<div>content1</div>
		<p>title3</p>
		<div>content2</div>
	</td></tr>
	</table>
</div>


樣式A的意思是,div標籤中,所有的p標籤文字顏色設定成紅色(這裡當然可以用h1、h2、h3避免,我們只是舉個例子)。所以title1-3都是紅色的。但有時候,我們希望title1是紅色的,而title2和title3都是灰色的,因此,要對樣式表做如下修改:
<style>
div > p {color:#f00;}
td > p {color:#333;}
</style>


    (5)兄弟組合:div + .className1 {styles...}
        和直接孩子組合類似,兄弟組合也規定了一種DOM和DOM之間的關係。上面例子翻譯過來是:找到一個class屬性等於className1的標籤A,A的”前面“有一個div標籤B。請注意”前面“的含義,意思就是A和B緊挨著,並且A和B有共同的父親,並且A在B後面渲染。那麼,借用上面的例子,如果想讓content1和content2的字型變成宋體,該怎樣寫樣式表?如下: