高級 CSS 選擇器指南,你學(xué)會(huì)了嗎?
一、基礎(chǔ)選擇器
在說高級選擇器之前,先來回顧一下CSS中的基礎(chǔ)選擇器。
1. 元素選擇器
最常見的 CSS 選擇器就是元素選擇器。選擇器通常將是某個(gè) HTML 元素:
h1 {
color: red;
font-size: 50px;
}
在 W3C 標(biāo)準(zhǔn)中,元素選擇器又稱為類型選擇器(type selector)。類型選擇器匹配文檔語言元素類型的名稱。類型選擇器匹配文檔樹中該元素類型的每一個(gè)實(shí)例。
2. ID 選擇器
id 選擇器用來指定具有ID的元素的樣式。ID 選擇器前面有一個(gè) # 號 - 也稱為棋盤號或井號。
#my_id {
color: red;
font-size: 50px;
}
需要注意,在一個(gè) HTML 文檔中,ID 選擇器會(huì)使用一次,而且僅一次。并且 ID 選擇器不能結(jié)合使用,因?yàn)?ID 屬性不允許有以空格分隔的詞列表。
3. 類選擇器
CSS類選擇器會(huì)根據(jù)元素的類屬性中的內(nèi)容匹配元素。類屬性被定義為一個(gè)以空格分隔的列表項(xiàng),在這組類名中,必須有一項(xiàng)與類選擇器中的類名完全匹配,此條樣式聲明才會(huì)生效。類選擇器也是我們最常用的選擇器之一。
.my_class {
color: red;
font-size: 50px;
}
二、通配選擇器
在CSS中,一個(gè)星號(*)就是一個(gè)通配選擇器,之所以如此命名,是因?yàn)樗毡檫m用于所有元素,可以匹配任意類型的HTML元素。那通配符選擇器有啥實(shí)際應(yīng)用呢?其會(huì)常用于全局樣式重置,比如 CSS 盒子模型重置:
*,
*::before,
*::after {
box-sizing: border-box;
}
這意味著我們希望所有元素在盒子模型計(jì)算中包括padding和border,而不是將這些寬度添加到任何定義的尺寸。例如,在以下規(guī)則中,.box寬度將是200px,而不是200px + 20px:
.box {
width: 200px;
padding: 10px;
}
三、屬性選擇器
CSS 屬性選擇器通過已經(jīng)存在的屬性名或?qū)傩灾灯ヅ湓?。這是一個(gè)非常強(qiáng)大的選擇器,但是通常沒有充分發(fā)揮其潛力。CSS 屬性選擇器可以獲得類似于正則表達(dá)式的匹配結(jié)果。這對于修改 BEM 風(fēng)格的系統(tǒng)或其他使用相關(guān)類名但可能不是單個(gè)通用類名的框架非常有用。來看一個(gè)例子:
[class*="component_"]
這個(gè)選擇器將選擇所有具有包含 component_ 字符串的類的元素。
可以通過在關(guān)閉屬性選擇器之前包含 i 來確保匹配不區(qū)分大小寫:
[class*="component_" i]
當(dāng)然我們也可以不指定屬性值,而是簡單的檢查它是否存在,例如下面的選擇器會(huì)選擇具有任何class值 的所有 a 標(biāo)簽:
a[class]
屬性選擇器可以用來執(zhí)行一些基本的可訪問性檢查,例如:
img:not([alt]) {
outline: 2px solid red;
}
這將為所有不包含 alt 屬性的圖像添加輪廓。
四、子代選擇器
當(dāng)使用 > 選擇符分隔兩個(gè)元素時(shí),它只會(huì)匹配那些作為第一個(gè)元素的直接后代(子元素)的第二元素。子組合選擇器是唯一處理元素級別的選擇器,并且可以組合以選擇嵌套元素。
? 選擇 article > p
<article>
<p>Hello world</p>
</article>
?? 未選擇 article > p
<article>
<blockquote>
<p>Hello world</p>
</blockquote>
</article>
有一個(gè)側(cè)邊欄導(dǎo)航列表,從語義上講,這會(huì)是一個(gè)包含 li 元素的 ul 元素列表。我們可能希望頂層鏈接的樣式與嵌套鏈接的樣式不同。要僅針對頂級鏈接,可以使用以下選項(xiàng):
nav > ul > li > a {
font-weight: bold;
}
五、通用兄弟選擇器
兄弟選擇符,位置無須緊鄰,只需同層級,A~B 選擇A元素之后所有同層級B元素。
例如,p~img 將為位于段落后面某個(gè)位置的所有圖像設(shè)置樣式,前提是它們屬于同一個(gè)父元素:
<article>
<p>Paragraph</p>
<h2>Headline 2</h2>
<img src="img.png" alt="Image" />
<h3>Headline 3</h3>
<img src="img.png" alt="Image" />
</article>
將通用兄弟選擇器與有狀態(tài)偽類選擇器(如:checked)相結(jié)合,可以產(chǎn)生有趣的效果。復(fù)選框的HTML結(jié)構(gòu)如下:
<input id="terms" type="checkbox" />
<label for="terms">terms</label>
只有選中復(fù)選框之后下面的樣式才會(huì)生效:
#terms:checked ~ p {
font-style: italic;
color: #797979;
}
六、相鄰兄弟選擇器
相鄰兄弟選擇器 (+) 介于兩個(gè)選擇器之間,當(dāng)?shù)诙€(gè)元素_緊跟在_第一個(gè)元素之后,并且兩個(gè)元素都是屬于同一個(gè)父元素的子元素,則第二個(gè)元素將被選中。
當(dāng)我們想給一個(gè)列表之間添加間隙時(shí),最常用的方式是給每個(gè)元素添加一個(gè)外邊距,但是這樣就還需要去除第一個(gè)元素的外邊距。我們可以使用相鄰兄弟選擇器來協(xié)助添加外邊距:
nav ul li + li {
margin-left: 2rem;
}
這樣就可以在列表項(xiàng)之間產(chǎn)生間隙效果,而無需在第一個(gè)項(xiàng)目上清除額外的邊距。
除此之外,我們還可以使用相鄰兄弟選擇器方便得給label標(biāo)簽和表單標(biāo)簽之間添加間隙:
label + input {
margin-left: 10px;
}
七、偽類選擇器
CSS 偽類是添加到選擇器的關(guān)鍵字,指定要選擇的元素的特殊狀態(tài)。這些極大地增強(qiáng)了 CSS 的功能,并啟用了過去經(jīng)常被錯(cuò)誤地歸入 JavaScript 的功能。
下面這些偽類選擇器是有狀態(tài)的:選擇器是有狀態(tài)的:
- :focus
- :hover
- :visited
- :target
- :checked
以下選擇器依賴于元素順序:
- :nth-child()、:nth-of-type()
- :first-child、:first-of-type
- :last-child、:last-of-type
- :only-child、:only-of-type
還有一些非常有用的偽類比如:not(),新支持的偽類:is(),以及隨著 CSS 自定義屬性(變量)的支持而出現(xiàn)在偽類:root。
nth系列的選擇器有著很多應(yīng)用,比如想實(shí)現(xiàn)一個(gè)交投背景色的表格,就可以使用nth-child選擇器,使用even(偶數(shù)行)或者odd(奇數(shù)行)關(guān)鍵字即可:
tbody tr:nth-child(odd) {
background-color: #ddd;
}
效果如下:
當(dāng)然也可以自己指定間隔規(guī)則:
li:nth-child(3n + 1) {
background-color: rebeccapurple;
}
這將第一個(gè)元素開始,每隔每三個(gè)元素選一個(gè):
我們可以使用:not()選擇器從選擇器中排除元素,上面我們就使用a:not([class])來定位沒有應(yīng)用class的鏈接。我們可以鏈接:not()選擇器使用,如果想為表單字段輸入創(chuàng)建規(guī)則,但不是某些類型就可以這樣寫:
input:not([type="hidden"]):not([type="radio"]):not([type="checkbox"])
也可以在:not()中包含其他偽類選擇器,例如排除:disabled狀態(tài)的按鈕:
button: not(: disabled);
八、偽元素選擇器
偽元素是一個(gè)附加至選擇器末的關(guān)鍵詞,允許對被選擇元素的特定部分修改樣式。它們在應(yīng)用中差異很大,目前最受支持的偽元素選擇器如下:
- ::after
- ::before
- ::first-letter
- ::first-line
- ::selection
::before 和 ::after 偽元素可以用來創(chuàng)建一個(gè)額外的元素,它們在視覺上似乎是DOM的一部分,但不是真正的HTMLDOM的一部分。由于它們的行為類似于真實(shí)元素,所以在使用flexbox或grid布局時(shí),它們會(huì)被計(jì)算為子元素,這大大增強(qiáng)了它們的功能。
在使用::before 和 ::after之前需要了解兩個(gè)重要的概念:
- 在使其可見之前需要設(shè)置content屬性,此屬性可以設(shè)置為空字符串;
- 一般情況下,::before將顯示在主元素內(nèi)容之前,而::after將顯示在其之后。
默認(rèn)情況下,它們的行為類似于內(nèi)聯(lián)元素:
當(dāng)給段落添加 display:flex 之后的效果如下:
切換為display:grid的效果如下:
我們可以使用偽元素::selection來定義選中文本的樣式:
::selection {
background: yellow;
color: black;
}