CSS選擇器結構邏輯圖
接下來按照結構邏輯圖具體講解各個選擇器的作用及用法;
基本選擇器
基本選擇器主要有以下5類:
*
: 通配選擇器;匹配html中的所有Html元素;E
: 元素選擇器;選中html中指定的某一類Html元素,如 h1 將選中所有的“h1”元素;#id
: ID選擇器;選中html中id屬性為特定值的所有元素;.class
: 類選擇器;選中html中class屬性為特定值的所有元素;s1,s2,s3
: 組群選擇器;對多個選擇器進行組合,同時定義相同的css樣式,定義組群選擇器主要是為了減少代碼的冗余;
層次選擇器(相對選擇器)
層次選擇器通過Html的DOM元素間的層次關系選擇元素;我也喜歡把層次選擇器稱為相對選擇器,就是找一個html元素作為基準,尋找相對于它的后代、孩子、兄弟等元素;
E F
: 后代選擇器;選中所有E容器所包含的類型為F的后代元素;E>F
: 子選擇器;選擇所有E容器中所有類型為F的子元素;
注意:”E的子元素F“是指F的父元素就是E,而”E的后代元素“是指F的父元素可能是E,或者F的父元素的父元素是E,或者F的父元素的父元素的父元素是E,... ;因此,"子"是"后代"的一個子集;E+F
: 相鄰弟選擇器;看了很多的教材都說這是相鄰兄弟選擇器,但是,它只能選擇緊靠E的,之后的F元素,而緊靠E的,之前的F元素不被選擇,所以,竊以為相鄰弟選擇器更加貼切,雖然不太學術;E~F
: 同輩弟選擇器;學術叫法是“通用選擇器”,實際上只能選擇與E具有相同父元素的、位于E之后的、符合F條件的所有元素;“同輩”即指與E具有相同父元素,“弟”即指位于E之后;eg.
<head>
<style media="screen">
#p2~p{color:red;}
</style>
</head>
<body>
<p id="p0">This paragraph 0</p>
<article id="div1">
<p id="p1">This is paragraph 1</p>
<p id="p2">This is paragraph 2</p>
<p id="p3">This is paragraph 3</p> <!--選中-->
<p id="p4">This is paragraph 4</p> <!--選中-->
<div>
<p id="p5">This is paragraph 5</p>
</div>
<p id="p6">This is paragraph 6</p> <!--選中-->
</article>
<p id="p7">This is paragraph 7</p>
</body>
只有id為p3、p4、p6的元素顏色變為紅色;
偽類選擇器
偽類選擇器語法書寫時,與其他的CSS選擇器寫法有所區別,其格式為:
E:pseudo-class{property:value;}
其中,E為html元素,pseudo-class是CSS的偽類選擇器名稱;即 偽類一定是依附于某個具體的元素的 ;偽類可以分為以下6類:
動態偽類選擇器
動態偽類體現了用戶和網站的交互狀態,動態偽類又分為兩類:
1. 鏈接偽類
因為只有a (anchor) 元素才具有的偽類,所以也稱為錨點偽類;
a:link
: 定義鏈接未被訪問時的樣式;
a:visited
: 定義鏈接被訪問后的樣式;
瀏覽器如何判斷錨點a是否訪問過?
答:經過在chrome上的測試,如果一個頁面的兩個a指向同一個url,那么如果點擊其中一個a,另一個a也將變為visited狀態,說明瀏覽器是通過檢測緩存來統一設置a的顏色的;
“ a#id:link ” 和 “ a:link#id是否等效 ” ?
答:等效,對于選擇器的擺放順序沒有特殊要求,只是元素選擇器必須放在第一個;
為什么有時候設置 a:link 的樣式會無效
答:a的狀態設置需要遵循 愛恨原則 ,即LoVe,HAte;即對錨的4個狀態的樣式定義需要按照先定義a:link,再定義a:visited,再定義a:hover,最后定義a:active的順序進行;否則可能樣式不能生效;
2. 用戶行為偽類
之所以不把這幾種狀態的偽類歸入錨點偽類,是因為這幾個偽類不僅僅針對a元素;
E:hover :
當鼠標移動到某個元素上時,該元素所顯示的樣式,適用于所有元素;
E:active :
當某個元素被激活時,所顯示的樣式,通常表現為a元素或按鈕元素被點擊時;
E:focus :
當某個元素獲得焦點時所顯示的樣式,適用于所有元素;
目標偽類選擇器
E:target :
選擇匹配E的所有元素,且匹配元素被相關URL指向;
要了解“目標偽類選擇器”,首先要了解url的組成結構:
<protocol>://<user>:<password>@<host>:<port>/<path>;<param>?<query>#<fragment>
protocol表示使用的傳輸協議,如htttp、ftp、smtp等;
有些url需要用戶名和密碼才能登陸,如ftp,則可以在url中直接指定user:password,如果沒有指定用戶名與密碼,將在瀏覽器端彈出用戶名-密碼輸入對話框;
host可以通過域名指定,也可以通過一個ip地址直接指定;
port表示提供服務的端口號,如http服務通常開80端口,ftp服務通常開21端口;
path表示服務器上資源的路徑;
param用于指定特殊參數的可選項;
query:當表單以Get方式提交給服務器時,表單元素的鍵值對將被放在query中;
fragment:通常是html中的元素的id號,當一個html文件非常長時,通過直接指定frag,可以讓瀏覽器定位到對應id的元素上,并顯示在瀏覽器視口中;
當我們通過指定fragment進行頁面訪問時,該fragment對應的元素就是目標偽類選擇器選中的元素;eg.有以下代碼:
<!--該文件的url為http://localhost/test.html-->
<head>
<style type="text/css">
#div1,#div2,#div3{height: 800;}
#div1,#div3{background-color: red;}
#div2{background-color: black;}
#div2:target{
background-color: green;
}
</style>
</head>
<body>
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
</body>
則以http://localhost/test.html
訪問該頁面時,div2的背景是黑色,而以http://localhost/test.html#div2
訪問該頁面時,頁面自動定位到div2上,并且div2的背景變為綠色;
語言偽類選擇器
E:lang(language) :
當某個元素指定了lang屬性時,所需要顯示的樣式,eg. :
<html>
<head>
<style type="text/css">
:lang(zh){
background: yellow;
}
:lang(en){
background: green;
}
div{height: 100px;}
</style>
</head>
<body>
<div id="div1" lang="en"></div>
<div id="div2"></div>
<div id="div3" lang="zh"></div>
</body>
</html>
div1的背景色為綠色,div2的背景色為白色,div3的背景色為黃色;
UI元素狀態偽類選擇器
UI元素狀態偽類選擇器主要作用于form表單元素上,以提高網頁的人機交互、操作邏輯以及頁面的整體美觀,使表單頁面更具有個性與品味;
E:checked :
選中狀態偽類選擇器;匹配選中的復選按鈕(checkbox) 或 單選按鈕(radio);
E:enabled :
啟用狀態偽類選擇器;匹配所有啟用的元素;
E:disabled :
禁用狀態偽類選擇器;匹配所有禁用的元素;
結構偽類選擇器
:first-child :
選擇第一個元素;
注意:E:first-child
和 E :first-child
的效果是不同的,E:first-child
是指E在某個容器中是第一個元素,則采用指定的樣式,這里的容器包括body、div等等;E :first-child
是指容器E中的第一個元素,無論其什么類型,采用指定的樣式;
:last-child :
選擇最后一個元素;同理,E:last-child
和 E :last-child
也是不同的;
:root :
因為在html文檔中,所有元素的根元素都是html,所以以下兩句是等價的
<style type="text/css">
html{color:red;}
:root{color:red;}
</style>
E F:nth-child(n) :
選中所有容器E中,從第一個元素開始數,序號為n的F元素;并且n可以是一個常數或者是an+b類型的數(其中a、b為常數,n從0開始計數),還可以是even或odd,even表示偶數,等價于2n,odd表示奇數,等價于2n+1;還是舉個具體的栗子吧:
<head>
<style type="text/css">
div h1:nth-child(3n+1){
color:red;
}
</style>
</head>
<body>
<div>
<h1 id="h_1">This is h_1</h1> <!--第1個元素-->
<h1 id="h_2">This is h_2</h1> <!--第2個元素-->
<h1 id="h_3">This is h_3</h1> <!--第3個元素-->
<h2 id="h_4">不是h1</h2> <!--第4個元素-->
<h1 id="h_5">This is h_5</h1> <!--第5個元素-->
<h1 id="h_6">This is h_6</h1> <!--第6個元素-->
<h1 id="h_7">This is h_7</h1> <!--第7個元素-->
<h1 id="h_8">This is h_8</h1> <!--第8個元素-->
<h1 id="h_9">This is h_9</h1> <!--第9個元素-->
</div>
</body>
上述代碼將會使在容器div中的、類型為h1的、序號為3n+1的元素被選中,所以id為h_1、h_7兩個元素選中,h_4因為不是h1元素而不被選,如果選擇器為div :nth-child(3n+1)
,則h_4也將被選中;
:nth-last-child :
與nth-child相似,只是元素序號從后往前數,若將上述代碼中的nth-child改為nth-last-child,則倒數第1、4、7個元素,即id為h_9、h_6、h_3的元素被選中;
E F:nth-of-type(n) :
nth-of-type與nth-child非常類似,只是只將類型為F的元素納入計序,而不是把所有E的子元素都進行計序;還是以上述代碼為栗子,若將nth-child改為nth-of-type,則id為h_1、h_5、h_8元素將被選中,因為它們分別是第0×3+1、1×3+1、2×3+1個h1元素;
E F:nth-last-of-type(n) :
與nth-of-type類似,只是從后往前對E元素進行計數;
E F:first-of-type :
等價于 E F:nth-of-type(1)
;
E F:last-of-type :
等價于 E F:nth-last-of-type(1)
;
E F:only-child :
當容器E只有一個子元素F時,F被選中;
E F:only-of-type :
當容器E中,沒有與F類型相同的元素時,即F的元素類型在容器E中惟一,F被選中;
E:empty :
當E元素沒有任何內容(包括空格也沒有)時所使用的樣式;
否定偽類選擇器
:not() :
起到過濾的效果,過濾掉具有某些屬性的元素,舉個栗子:
<head>
<style type="text/css">
div h1:not(:nth-child(odd)){
color:red;
}
</style>
</head>
<body>
<div>
<h1 id="h_1">This is h_1</h1> <!--第1個元素-->
<h1 id="h_2">This is h_2</h1> <!--第2個元素-->
<h1 id="h_3">This is h_3</h1> <!--第3個元素-->
<h2 id="h_4">不是h1</h2> <!--第4個元素-->
</div>
</body>
該代碼將會選中在div中,序號為非奇數的h1元素,則只有id為h_2的元素被選中;
偽元素
偽元素主要用于定位文檔中的文本,而不是html元素;也是因為它們在html中沒有對應的元素,所以被稱為偽元素;
需要說明的是,偽元素并不是在CSS3中才出現的,比如
*:first-line 、:first-letter 、:before 、 :after *
CSS3為了區分偽元素和偽類,對偽元素進行了規范化,將單冒號變為了雙冒號,即變為了
::first-line 、 ::first-letter 、 ::before 、 ::after
另外,偽元素增加了一個 ::selection ;瀏覽器為了兼容,如果偽元素前使用單冒號也能被解析為偽元素;
::first-letter :
用于定位元素文檔中的第一個字母;eg.
<style type="text/css">
h1::first-letter{
background-color: grey;
color: blue;
}
</style>
上述代碼將會使html中所有的h1元素第一個字符變為灰底藍字;
::first-line :
用于定位元素文檔中的第一行;eg.
<head>
<style type="text/css">
h1::first-line{
background-color: grey;
color: deepskyblue;
}
</style>
</head>
<body>
<h1 id="h_1">line1<br>line2</h1>
</body>
上述代碼中,"line1"和"line2"以換行<br> 換行分隔;在瀏覽器中,"line1"為灰底藍字,而"line2"為正常顯示;
::before :
在某元素的前面添加內容;
::after :
在某元素的后面添加內容;eg.
<head>
<style type="text/css">
p::before{content:"Before.";}
p::after{content: "After.";}
</style>
</head>
<body>
<p>This is paragraph.</p>
</body>
將在頁面中顯示:
Before.This is paragraph.After.
查看頁面源碼如下:
可見,偽元素::before
和::after
被添加到p 內部 的前面和后面,并且內容與設置的content相同;
設置偽元素時,必須設置器content屬性,否則偽元素將無效;
content屬性可以有以下內容:
字符串
: 作為偽元素的內容添加到主元素中;若字符串中有html代碼,這些代碼以文本形式顯示,而不會轉化為真正的html內容顯示;attr(attr_name)
: 偽元素的某個內容跟主元素的某個屬性進行關聯;url()
: 引入外部資源;eg.
<style>
p::before{content:url("./x.png")}
</style>
將在p中引入圖片顯示在最前面;
-
counter()
: 調用計數器,可以不使用列表元素實現序號問題;
::selection
: 用來匹配突出顯示的文本,該偽元素僅接受兩個屬性--background和color;eg.
<head>
<style type="text/css">
p::selection{
background: yellow;
color:red;
}
</style>
</head>
<body>
<p>This is paragraph.</p>
</body>
則在頁面中通過鼠標選中p的某些文本,這些文本將會以黃底紅字顯示;
屬性選擇器
E[attr]
: 選擇含有屬性attr的所有元素,E可以省略;attr不能加引號;
E[attr=val]
: 選擇屬性attr為val的所有E元素;val不區分大小寫
E[attr|=val]
: 選擇屬性attr為val或以 val- 開始的E元素;
E[attr^=val]
: 選擇屬性attr為val或以 val 開始的E元素;
E[attr$=val]
: 選擇屬性attr為val或以val結尾的E元素;
E[attr*=val]
: 屬性attr的任意位置有val值的所有E元素;
E[attr~=val]
: 屬性attr中以空格分割為多個值后,其中有val的所有E元素;
選擇器的優先級
多個選擇器可能選中了同一個對象,那哪個選擇器定義的樣式真正起作用,這就需要定義選擇器的優先級;
在某個屬性后面添加!important,將會強制使用該處的屬性覆蓋其他地方的屬性,eg.
<head>
<style type="text/css">
div :first-child{color:red !important;}
</style>
</head>
<body>
<div>
<p style="color:green;">This is paragraph.</p>
</div>
</body>
其中的p元素字體為紅色,而不是內聯樣式指定的綠色;
結果chrome測試,選擇器的優先級為:
有!important的屬性
內聯樣式
id選擇器
類選擇器
層次選擇器
偽類選擇器
屬性選擇器
元素選擇器
通配選擇器
對于同一優先級的選擇器,當它們選中同一元素,并對該元素的同一個屬性進行定義而產生沖突時,后定義的樣式將覆蓋前定義的樣式;
PS (PostScript) : 參考很多前人的文章,沒有一一列出,敬請諒解;主要參考書籍為大漠老師的《圖解CSS3--核心技術與案例實戰》。有寫的不好的地方或者錯誤的地方歡迎指正,感謝!