你知道的和你不知道的所有選擇器。不包含尚未廣泛實現的,也不包含已棄用的。
基本的選擇器規則(Selector)
型別(Type)選擇器
直接用標籤匹配特定的元素
span {
...
}
p {
...
}
類(Class)選擇器
以.開頭,匹配含有這個 class 的元素
.info {
...
}
p.info { /* 匹配含有 info 類的 p 元素 */
...
}
.info.log { /* 匹配同時含有 info 和 log 類的元素 */
...
}
ID 選擇器
以#開頭,匹配對應 id 的元素。
#info {
...
}
p#info {
...
}
引數(Attribute)選擇器
除了 id 和 class,也可以篩選其他引數進行匹配,並且除了全字匹配還提供了多重手段。
/* 存在 title 的 <a> 元素 */
a[title]
/* 存在 href 屬性並且值為"https://example.org"*/
a[href="https://example.org"]
/* 存在 href 屬性並且內容包含"example"*/
a[href*="example"]
/* 存在 href 屬性並且以".org"結尾 */
a[href$=".org"]
/* 存在 href 屬性並且以"https"開頭 */
a[href^="https"]
/* class 用空格分割的列表中存在 logo。效果等於.logo。用於class這樣空格分隔的屬性 */
a[class~="logo"]
/* 存在 lang 屬性並且以"zh"或"zh-"開頭。用於匹配lang屬性*/
div[lang|="zh"]
/* i 表示忽略大小寫 */
a[href="https://example.org" i]
萬用字元
*表示萬用字元,可以匹配任何元素。效能較低,謹慎使用。
組合選擇器(Combinator)
組合選擇器可以連線多個元素。
子選擇器和後代選擇器
子選擇器用>表示,匹配第一個元素的直接後代的第二個元素(即 child)。後代選擇器只需要用空格隔開,不要求是直接後代(即 descendant)。
p span{ /* 所有 p 元素中的 span 元素 */
color:red;
}
p > span{ /* 所有 p 元素中的直接子元素 span 元素 */
color:blue;
}
<p>
<span>p span和p>span都匹配</span>
<p>
<span>只匹配p span</span>
</p>
</p>
注意:p.info 和 p .info 是不一樣的。
兄弟選擇器和相鄰兄弟選擇器
與上文類似,兄弟選擇器用+表示,匹配第一個元素直接相鄰之後的第二個元素。相鄰兄弟選擇器用~表示,只要求是兄弟(同一個父元素),不要求相鄰。
img + p /* 緊跟在img後面的p */
img ~ p /* 和img有相同父元素的p */
<p>
<img/>
<p>匹配 img+p 和 img~p</p>
<p>只匹配 img~p</p>
</p>
選擇器列表
選擇器列表用逗號,表示,用逗號連線的選擇器共同使用規則。
span, div{}
span, .info{}
注意:1. p span, .info 會匹配 p span 和 .info,而不是 p span 和 p .info,實現後者需要:is
2. 逗號選擇器是阻塞的,如果其中一個標籤不合法,整個規則都不會生效
偽類(Pseudo-Classes)
CSS 偽類是新增到選擇器的一種關鍵字,表示這個元素的特殊狀態。例如,偽類 :hover 可以用於選擇一個按鈕,當使用者的指標懸停在按鈕上時,設定此按鈕的樣式。但這個類並不真的在 class 中,所以叫偽類。偽類用:表示。
連結和按鈕相關
常用:
:link
表示未訪問的連結,匹配尚未訪問的連結,預設一般是藍色。:visited
表示訪問過的連結,一般是紫色。出於隱私限制,這個偽類用的越來越少。:hover
表示滑鼠移向元素時的情況:active
表示滑鼠正在點選元素的情況
.info:link{
color: blue;
}
.info:hover{
color: red;
}
.info:active{
color: purple;
}
<a href="example">a link</a>
注意: 1. 有 href 屬性的 a 標籤才是連結,沒有的不算。:link 也不只有 a 標籤,其他標籤的連結也可以(比如 link 標籤)。
2. LVHA 規則:定義同一個連結多種情況的樣式時,要按 link visited hover active 的順序。這是因為他們的優先順序相同,如果後出現的覆蓋先出現的就會出現問題,比如將 hover 放到 active 後,那點選連結時兩個偽類都滿足,hover 會覆蓋 active 導致 active 的設定不生效。
:any-link
表示未訪問的和已訪問的連結,包括 link 和 visited。
表單輸入相關
:checked
表示正選中的單選框(radio),核取方塊(checkbox)和下拉選單項(option)元素:default
表示單選框,核取方塊和下拉選單項中預設的那個元素:disabled
表示被禁用的元素:enabled
表示被啟用的元素:focus
表示獲得焦點的元素:focus-within
表示獲得焦點或者後代獲得焦點的元素:focus-visible
表示獲得焦點且焦點可見的元素。這是什麼意思呢?
對於一個 input 輸入框,無論用滑鼠點選它還是用 tab 切到它,樣式都是一樣的(一般是加上一圈 outline),符合人們的習慣。
但是對於一個 button 來說,用滑鼠點選它會觸發 :focus ,而用 tab 切換到它也會觸發 :focus(雖然沒有按下去),這就有點奇怪了。
<button> A </button>
<button> B </button>
<style>
button:focus{ background-color: red;} /* tab 過去也生效 */
/*button:focus-visible{ background-color: green;*/}</style>
我們設定 :focus,顯然是給滑鼠按下去準備的,卻忘了鍵盤 tab 獲得焦點的情況。對於 button,用滑鼠點選的時候,你知道自己在點哪,就不算 :focus-visible;而用 tab 切換或者 js 跳轉時,你需要不一樣的焦點提醒,此時 :focus-visible 生效,這樣就可以區分二者。對於輸入框來說,所有聚焦都觸發 :focus-visible。取消掉註釋,兩種focus樣式就不再相同了。
其實瀏覽器的預設樣式就考慮到了,預設按鈕點選時會變深,tab 時則是加上一圈 outline。自己的樣式會讓預設樣式失效,如果需要精細的設計,就可以使用 :focus-visible。一個案例
:in-range
表示值在min到max範圍內的輸入框:out-of-range
表示值不在min到max範圍內的輸入框:indeterminate
表示“不確定”的表單元素,包括設定了 indeterminate 的選框,尚未選擇的單選框,尚未完成的進度條。:valid
表示輸入合法的輸入框:invalid
表示輸入不合法的輸入框:required
表示設定必填的輸入:optional
表示設定不是必填的輸入:placeholder-shown
表示擁有 placeholder 的輸入框:read-only
表示設定了只讀屬性的輸入:read-write
表示可修改的輸入:autofill
表示按下瀏覽器自動填充功能的輸入框
DOM 子節點相關
:empty
表示沒有子元素的元素(文字節點也算元素,註釋不算)。比如<p>assa</p>
並不能匹配,<p></p>
才可以。:first-child
表示“是父元素的第一個子節點”。:last-child
表示“是父元素的最後一個子節點”。:first-of-type
表示“是父元素的第一個對應元素的子節點”。:last-of-type
表示“是父元素的最後一個對應元素的子節點”。
<p>
<span>p :first-child 或者 span:first-child</span>
<a>p a:first-of-type</a>
<a></a>
</p>
:nth-child
後接整數或一次函式,選中特性序號的孩子節點。
p :nth-child(2) /* 第二個孩子 */
p :nth-child(2n) /* 第2,4,6……個元素,n從0開始 */
p :nth-child(2n+1) /* 第1,3,5……個元素 */
p :nth-child(4n+3) /* 第4,7,10……個元素 */
p :nth-child(-n+3) /* 第3,2,1個元素 */
:nth-last-child
同上,不過是倒著數:nth-of-type
同上,也就是:first-child
和:first-of-type
的區別,限定了元素:nth-last-of-type
同上。:only-child
表示沒有其他兄弟的元素:only-of-type
表示沒有其他相同元素兄弟的元素
DOM 相關的其他偽類
:has
表示“擁有……”的,它的引數是一個逗號選擇器列表。注意不能 has 巢狀。Firefox 暫不支援
p:has(span, .info) /* 含有 span或.info的 p */
h1:has(+h2) /* 滿足h1+h2的 h1 */
:is
和:where
後接選擇器列表,表示多選一。他們的區別是 is 計算優先順序,而 where 不計入。p :is(span, .info)
表示p span 和 p .info:not
後接選擇器列表,和 is 相反,表示排除這些選項,選中不是這些元素的元素。:root
在 HTML 文件中,:root 就等於<html>
元素
其他
:modal
表示“模態”,即 js 用 showModal 構造的阻塞對話方塊的樣式。一個案例:lang
用於選中元素的語言屬性:target
表示當前錨點代表的元素。比如當前 url 是example.org#title
,那麼 id 為 title 的元素就會被匹配:defined
表示所有的預設標籤(div span)和用 jscustomElements.define
定義的自定標籤,有了這個偽類,就可以把自定標籤定義之前和之後區分:host
匹配所有 shadow root 的根元素,也可以加上括號,:host()
後接選擇器,表示符合條件的根元素。:host-context
後接選擇器,匹配在 shadow DOM 中符合條件的元素。
偽元素(Pseudo-elements)
偽元素是一個附加至選擇器末的關鍵詞,允許你對被選擇元素的特定部分修改樣式。但這個部分在 dom 中並不存在,所以叫做偽元素。用::表示,但像偽類一樣只打一個冒號也可以。
::after
在已選中元素之後再構造一個元素::before
在已選中元素之前再構造一個元素::first-letter
匹配本元素第一個字元::first-line
匹配本元素第一個行::marker
匹配一個 list 的元素的 marker,比如列表前面的數字序號和小圓點。::placeholder
匹配輸入框的 placeholder 文字::selection
表示元素中被使用者框選的部分
其他
::part
後接字串,匹配 shadow tree 中滿足part條件的元素::file-selector-button
代表一個檔案提交按鈕::cue
匹配這個元素的 WebVTT 提示::slotted
匹配模板中的插槽元素::target-text
匹配當前的文字錨點所在的文字。