- 作者:陳大魚頭
- github: KRISACHAN
前言
CSS 選擇器是 CSS 世界中非常重要的一環。
在 CSS 2 之後,所有的 CSS 屬性都是按模組去維護的。
CSS 選擇器也是如此,然而如今也已經發布了第四版 —— CSS Selectors Level 4 ,這一版最早的草案釋出於2011年09月29日,最後更新是2018年11月21日。
下面讓我們一起來看看 Level 4 新推出的一些選擇器。
正文
下面我們按照型別來劃分
邏輯組合(Logical Combinations)
在這個分類下,我們有以下四個選擇器:
:not()
其實 :not()
不算是新標籤,不過在 Level 4 裡,增加了多選的功能,程式碼如下:
/* 除了.left, .right, .top之外所以的div的盒子模型都會變成flex
*/
div:not(.left, .right, .top) {
display: flex;
}
/* 等價於 */
div:not(.left), div:not(.right), div:not(.top) {
display: flex;
}
相容性如下:
額。。。還不能用
:is()
:is()
偽類將選擇器列表作為引數,並選擇該列表中任意一個選擇器可以選擇的元素。這對於以更緊湊的形式編寫大型選擇器非常有用。
看個栗子:
/* 選擇header, main, footer裡的任意一個懸浮狀態的段落(p標籤) */
:is(header, main, footer) p:hover {
color: red;
cursor: pointer;
}
/* 等價於 */
header p:hover,
main p:hover,
footer p:hover {
color: red;
cursor: pointer;
}
相容如下:
:where()
:where()
偽類接受選擇器列表作為它的引數,將會選擇所有能被該選擇器列表中任何一條規則選中的元素。
其實就是跟 :is()
,唯一不同的就是 :where()
的優先順序總是為 0 ,但是 :is() 的優先順序是由它的選擇器列表中優先順序最高的選擇器決定的。
程式碼如下:
<style>
:is(section.is-styling, aside.is-styling, footer.is-styling) a {
color: red;
}
:where(section.where-styling, aside.where-styling, footer.where-styling) a {
color: orange;
}
footer a {
color: blue;
}
</style>
<article>
<h2>:is()-styled links</h2>
<section class="is-styling">
<p>Here is my main content. This <a href="https://mozilla.org">contains a link</a>.
</section>
<aside class="is-styling">
<p>Here is my aside content. This <a href="https://developer.mozilla.org">also contains a link</a>.
</aside>
<footer class="is-styling">
<p>This is my footer, also containing <a href="https://github.com/mdn">a link</a>.
</footer>
</article>
<article>
<h2>:where()-styled links</h2>
<section class="where-styling">
<p>Here is my main content. This <a href="https://mozilla.org">contains a link</a>.
</section>
<aside class="where-styling">
<p>Here is my aside content. This <a href="https://developer.mozilla.org">also contains a link</a>.
</aside>
<footer class="where-styling">
<p>This is my footer, also containing <a href="https://github.com/mdn">a link</a>.
</footer>
</article>
:is()
跟 :where()
對比效果圖如下:
相容性如下:
:has()
:has()
偽類代表一個元素,其給定的選擇器引數(相對於該元素的 :scope)至少匹配一個元素。
:has()
接受一個選擇器組作為引數。在當前規範中 :has()
並未列為實時選擇器配置的一部分,意味著其不能用於樣式表中。
語法如下:
// 下面的選擇器只會匹配直接包含 <img> 子元素的 <a> 元素
a:has(> img)
// 下面的選擇器只會匹配其後緊跟著 <p> 元素的 <h1> 元素:
h1:has(+ p)
相容性如下:
嗯,全紅。。。
語言偽類(Linguistic Pseudo-classes)
:dir()
:dir()
偽類匹配特定文字書寫方向的元素。在HTML中, 文字方向由dir
屬性決定。其他的文件型別可能有其他定義文字方向的方法。
:dir()
並不等於使用 [dir=…]
屬性選擇器。後者匹配 dir
的值且不會匹配到未定義此屬性的元素,即使該元素繼承了父元素的屬性;類似的, [dir=rtl]
或 [dir=ltr]不會匹配到dir屬性的值為auto的元素。而
:dir()
會匹配經過客戶端計算後的屬性, 不管是繼承的dir值還是dir值為auto的。
例子如下:
<style>
:dir(ltr) {
background-color: yellow;
}
:dir(rtl) {
background-color: powderblue;
}
</style>
<div dir="rtl">
<span>test1</span>
<div dir="ltr">test2
<div dir="auto">עִבְרִית</div>
</div>
</div>
效果如下:
相容性如下:
又是一片紅。。
:lang()
:lang()
偽類基於元素語言來匹配頁面元素。
例子如下:
/* 下例表示選擇文字語言帶有-TN的div元素 (ar-TN, fr-TN). */
div:lang(*-TN) {
background-color: green
}
瀏覽器支援狀態:沒有一個支援的。
位置偽類(Location Pseudo-classes)
:any-link
:any-link
偽類 選擇器代表一個有連結錨點的元素,而不管它是否被訪問過,也就是說,它會匹配每一個有 href 屬性的 <a>
、<area>
或 <link>
元素。因此,它會匹配到所有的 :link
或 :visited
。
例子如下:
<style>
a:any-link {
border: 1px solid blue;
color: orange;
}
/* WebKit 核心瀏覽器 */
a:-webkit-any-link {
border: 1px solid blue;
color: orange;
}
</style>
<a href="https://example.com">External link</a><br>
<a href="#">Internal target link</a><br>
<a>Placeholder link (won't get styled)</a>
效果如下:
相容性如下:
:local-link
:local-link
偽類可以單獨格式化本地連結(原文是local links
)(內部連結)。
例子如下:
a:local-link {
text-decoration: none;
}
效果 & 相容性
沒有一個瀏覽器是支援的,看不到效果
:target-within
:target-within
偽類適用於:target
所匹配的元素,以及它DOM節點內所有匹配的元素。
例子如下:
div:target-within {
border: 2px solid black;
}
效果 & 相容性
沒有一個瀏覽器是支援的,看不到效果
:scope
:scope
偽類表示作為選擇器要匹配的作用域的元素。不過目前它等效於 :root
。
因為尚未有瀏覽器支援CSS的區域性作用域。
例子如下:
:scope {
background-color: lime;
}
相容性如下:
瀏覽器演算法不支援,相容有跟沒沒區別~
使用者行為偽類(User Action Pseudo-classes)
:focus-visible
當元素匹配 :focus
偽類並且客戶端(UA)的啟發式引擎決定焦點應當可見(在這種情況下很多瀏覽器預設顯示“焦點框”。)時,:focus-visible
偽類將生效。
這個選擇器可以有效地根據使用者的輸入方式(滑鼠 vs 鍵盤)展示不同形式的焦點。
例子如下:
<style>
input, button {
margin: 10px;
}
.focus-only:focus {
outline: 2px solid black;
}
.focus-visible-only:focus-visible {
outline: 4px dashed darkorange;
}
</style>
<input value="Default styles"><br>
<button>Default styles</button><br>
<input class="focus-only" value=":focus only"><br>
<button class="focus-only">:focus only</button><br>
<input class="focus-visible-only" value=":focus-visible only"><br>
<button class="focus-visible-only">:focus-visible only</button>
效果如下:
相容性如下:
目前只有Chrome 67+ 相容...
:focus-within
:focus-within
偽類適用於:focus
所匹配的元素,以及它DOM節點內所有匹配的元素。
例子如下:
<style>
form {
border: 1px solid;
color: gray;
padding: 4px;
}
form:focus-within {
background: #ff8;
color: black;
}
input {
margin: 4px;
}
</style>
效果如下:
時間尺寸偽類(Time-dimensional Pseudo-classes)
:current
&& :past
&& :future
這個偽類選擇器會選擇HTML5
中<video>
的語言渲染以及播放過程中的時間維度相對元素。所有相關的選擇器都像:matches()
。這幾個偽類選擇器的區別在於:past
會選擇:current
所選的元素之前的所有節點。所以,:future
就是指之後的所有節點了。
例子如下:
/* Current */
:current(p, span) {
background-color: yellow;
}
/* Past */
:past,
/* Future */
:future {
display: none;
}
相容性如下:
目前沒有任何瀏覽器支援
輸入偽類(The Input Pseudo-classes)
:read-only
與 :read-write
:read-only
偽類選擇器表示當前元素是使用者不可修改的。
:read-write
偽類選擇器表示當前元素是使用者可修改的。這個偽類選擇器可以使用在一個可輸入的元素或 contenteditable
元素(HTML5 屬性)。
例子如下:
<style>
:read-only {
font-size: 20px;
color: green;
}
:read-write {
border: 1px solid orange;
font-size: 18px;
}
</style>
<input type="text" placeholder='text here'>
<input type="tel" placeholder='number here'>
<select>
<option>1</option>
<option>2</option>
</select>
效果如下:
相容性如下:
:placeholder-shown
:placeholder-shown
偽類 在 <input>
或 <textarea>
元素顯示 placeholder text 時生效。
例子如下:
<style>
input {
border: 2px solid black;
padding: 3px;
}
input:placeholder-shown {
border-color: silver;
}
</style>
<input placeholder="Type something here!">
效果如下:
相容性如下:
:default
:default
偽類選擇器 表示一組相關元素中的預設表單元素。
該選擇器可以在 <button>
, <input type="checkbox">
, <input type="radio">
, 以及 <option>
上使用。
例子如下:
<style>
input:default {
box-shadow: 0 0 2px 1px coral;
}
input:default + label {
color: coral;
}
</style>
<input type="radio" name="season" id="spring">
<label for="spring">Spring</label>
<input type="radio" name="season" id="summer" checked>
<label for="summer">Summer</label>
<input type="radio" name="season" id="fall">
<label for="fall">Fall</label>
<input type="radio" name="season" id="winter">
<label for="winter">Winter</label>
效果如下:
相容性如下:
:indeterminate
:indeterminate
偽類選擇器表示狀態不確定的表單元素。
它支援:
-
<input type="checkbox">
元素,其indeterminate
屬性被JavaScript設定為true
。 -
<input type="radio">
元素, 表單中擁有相同name
值的所有單選按鈕都未被選中時。 - 處於不確定狀態的
<progress>
元素
例子如下:
<style>
input, span {
background: red;
}
:indeterminate, :indeterminate + label {
background: lime;
}
progress {
margin: 4px;
}
progress:indeterminate {
opacity: 0.5;
background-color: lightgray;
box-shadow: 0 0 2px 1px red;
}
</style>
<div>
<input type="checkbox" id="checkbox">
<label for="checkbox">Background should be green</label>
</div>
<br />
<div>
<input type="radio" id="radio">
<label for="radio">Background should be green</label>
</div>
<br />
<progress></progress>
<script>
'use strict'
const inputs = document.querySelectorAll('input')
inputs.forEach(input => {
input.indeterminate = true
})
</script>
效果如下:
相容性如下:
:valid
與 :invalid
判斷有效性的偽類選擇器(:valid
和:invalid
)匹配有效或無效,<input>
或<form>
元素。
:valid
偽類選擇器表示值通過驗證的<input>
,這告訴使用者他們的輸入是有效的。
:invalid
偽類選擇器表示值不通過通過驗證的<input>
,這告訴使用者他們的輸入是無效的。
例子如下:
<style>
input:valid {
outline: 1px solid green;
}
input:invalid {
outline: 1px solid red;
}
</style>
輸入文字:
<input type="text" pattern="[\w]+" required />
<br />
輸入電話號碼:
<input type="tel" pattern="[0-9]+" required />
效果如下:
相容性如下:
:in-range
與 :out-of-range
如果一個時間或數字<input>
具有max
或min
屬性,那麼:in-range
會匹配到輸入值在指定範圍內的<input>
,:out-of-input
則匹配輸入值不在指定範圍的<input>
。如果沒有規定範圍,則都不匹配。
例子如下:
<style>
li {
list-style: none;
margin-bottom: 1em;
}
input {
border: 1px solid black;
}
input:in-range {
background-color: rgba(0, 255, 0, 0.25);
}
input:out-of-range {
background-color: rgba(255, 0, 0, 0.25);
border: 2px solid red;
}
input:in-range + label::after {
content: 'okay.';
}
input:out-of-range + label::after {
content: 'out of range!';
}
</style>
<form action="" id="form1">
<ul>Values between 1 and 10 are valid.
<li>
<input id="value1" name="value1" type="number" placeholder="1 to 10" min="1" max="10" value="12">
<label for="value1">Your value is </label>
</li>
</ul>
</form>
效果如下:
相容性如下:
:required
與 :optional
偽類選擇器:required
和:optional
匹配了<input>
,<select>
, 或 <textarea>
元素。
:required
表示“必填”
:optional
表示“可選”
例子如下:
<style>
input:required {
border: 1px solid orange;
}
input:optional {
border: 1px solid green;
}
</style>
必填的:<input type="text" required>
<br />
可選的:<input type="text">
效果如下:
相容性如下:
:required
的相容性在上面有。
:blank
:blank
偽類選擇器 用於匹配如下節點:
- 沒有子節點;
- 僅有空的文字節點;
- 僅有空白符的文字節點。
有點類似於:empty
,但是比:empty
寬鬆,目前還是沒有任何一款瀏覽器支援。
:user-invalid
:user-invalid
偽類選擇器匹配輸入錯誤的元素。不過跟其它的輸入偽類不同的是,它僅匹配使用者輸入時的錯誤,而不是靜默狀態下的錯誤,這樣就會比較人性化,可惜,目前還是沒有任何一款瀏覽器支援。
樹型偽類(Tree-Structural pseudo-classes)
:nth-child
與 :nth-last-child
:nth-child
與 :nth-last-child
並不是 Level 4 才推出的偽類選擇器,但是在 Level 4 裡 新增了在元素組裡匹配的功能。
語法如下::nth-child/nth-last-child(An + B [of S] ?)
例子如下:
:nth-child(-n+3 of li.important)
上面的例子通過傳遞選擇器引數,選擇與之匹配的第n個元素,這裡表示li.important
中前三個子元素。
它跟以下規則不同:
li.important:nth-child(-n+3)
這裡表示的時候如意前三個子元素剛才是li.important
時才能被選擇得到。
相容性如下:
(魚頭注:牛皮,Safari居然彎道超車了,不過別的瀏覽器不支援,也沒啥用...)
網格選擇器(Grid-Structural Selectors)
||
||
組合器選擇屬於某個表格行的節點。
例子如下:
<style>
col.selected || td {
background: gray;
color: white;
font-weight: bold;
}
</style>
<table border="1">
<colgroup>
<col span="2"/>
<col class="selected"/>
</colgroup>
<tbody>
<tr>
<td>A
<td>B
<td>C
</tr>
<tr>
<td colspan="2">D</td>
<td>E</td>
</tr>
<tr>
<td>F</td>
<td colspan="2">G</td>
</tr>
</tbody>
</table>
上面的例子可以使C,E 與 G單元格變灰。
很可惜,目前還是沒有任何瀏覽器給予支援。
:nth-col()
與 :nth-last-col()
偽類選擇器:nth-col()
與 :nth-last-col()
表示選擇正向或反向的表格行的節點。
語法和:nth-child
與 :nth-last-child
類似,只不過它是選擇表格內的元素。
目前還是沒有任何瀏覽器支援。
最後
總結
以上便是CSS選擇器 Level 4 裡新出的所有選擇器,其實都是非常有用的,雖然有些選擇器的瀏覽器支援度並不樂觀的。
希望各大瀏覽器廠商可以趕快增加對它們的支援吧。