CSS4中出现的一些新型选择器
Negation pseudo-class——:not()
:not()
用于将符合规则的元素剔除,将样式规则应用于其他元素上。在 CSS3 中已经有 :not()
,不过在 CSS3 中只能使用简单的匹配规则,例如 :not(p)
用来选择不是 <p></p>
的元素。而在 CSS4 中,可以应用更复杂的匹配规则,但是同样地不允许嵌套使用,例如 :not(:not(...))
。
.negation {
color: black;
}
.negation .default:not([data-red="no"]) {
color: red;
}
.negation .default a {
color: green;
}
.negation .default a:not([rel="green"], [rel="default"]) {
color: blue;
}
<div class="negation">
<div class="default" data-red="no">
<a href="https://www.baidu.com" rel="green">这里是绿色</a>
<a href="https://www.ele.me" rel="default">这里也是绿色</a>
<a href="https://www.sina.com" rel="blue">这里是蓝色</a>
</div>
<div class="default" data-red="no">
这里是黑色
</div>
<div class="default" data-red="yes">
这里是红色
</div>
</div>
:not()
小提示
我们可以利用 :not()
来对 CSS 样式进行一个优先级提升,例如 div:not(span) {…}
跟 div {…}
是同个概念,但是明显地前者的优先级更高。
想解锁更多
:not()
的使用姿势就去看 The Negation Pseudo-class 草案。
Matches-any Pseudo-class——:matches 伪类
:matches()
用于匹配所述规则的元素,并应用相应的样式规则,同样不允许嵌套使用,-webkit-any()
和 -moz-any()
是它的两个兼容性写法。
.matches {
color: black;
}
.matches :matches(span, div) :matches(span, div) {
color: green;
}
/*
等同于
.matches span div,
.matches span span,
.matches div span,
.matches div div {
color: green;
}
*/
.matches :-webkit-any(span, div) :-webkit-any(span, div) {
color: green;
}
.matches :-moz-any(span, div) :-moz-any(span, div) {
color: green;
}
.matches :matches(.a, .b) :matches(.a, .b) {
color: red;
}
/*
等同于
.matches .a .a,
.matches .a .b,
.matches .b .a,
.matches .b .b {
color: red;
}
*/
.matches :-webkit-any(.a, .b) :-webkit-any(.a, .b) {
color: red;
}
.matches :-moz-any(.a, .b) :-moz-any(.a, .b) {
color: red;
}
<div class="matches">
<span>
<div>绿色</div>
</span>
<span>
<span>绿色</span>
</span>
<div>
<span>绿色</span>
</div>
<div>
<div>绿色</div>
</div>
<div class="a">
<div class="b">红色</div>
</div>
<div class="b">
<div class="a">红色</div>
</div>
<div class="a">
<div class="a">红色</div>
</div>
<div class="b">
<div class="b">红色</div>
</div>
</div>
想解锁更多姿势就去看 The Matches-any Pseudo-class 草案
Case-Sensitivity——不区分大小写匹配标识
Case-Sensitivity
用于声明某个匹配规则中,对字符串或者某个 value 的匹配不区分大小写。该标志声明于 ]
即右中括号之前,例如 [data-value="case" i]
,其中的 i
就是 Case-Sensitivity 标识。
.case-sensitivity :matches([data-value="case" i]) {
color: yellow;
}
<div class="case-sensitivity">
<p data-value='Case'>Case</p>
<p data-value="case">case</p>
</div>
以上的例子,data-value
虽然既有大写也有小写,但是由于我们声明了 Case-Sensitivity
,所以无论大小写都会被匹配。像例子中 case
,Case
,CASE
等都会被匹配。
想解锁更多姿势就去看 Case-sensitivity 草案
The Directionality Pseudo-class——:dir()
:dir()
伪类用于匹配符合某个方向性的元素,例如 :dir(ltr)
和 dir(rtl)
。顾名思义,ltr
表示 left to right
,即方向从左到右,rtl
表示 right-to-left
,即方向从右到左。值得注意的是,使用 :dir()
匹配元素和使用 [dir=...]
在某个程度上是一样的效果,但是一个区别是 [dir=...]
无法匹配到没有显示声明 dir
的元素,但是 :dir()
却可以匹配到由浏览器计算得到或者继承来的 dir
属性的元素,详情可以看一下草案。
.dir :dir(ltr) {
color: blue;
}
.dir :dir(rtl) {
color: green;
}
<div class="dir">
<p dir="ltr">从左到右</p>
<p dir="rtl">从右到左</p>
</div>
想解锁更多姿势就去看 The Directionality Pseudo-class 草案
The Language Pseudo-class——:lang()
:lang()
用于匹配声明了 lang=value
的元素,并且可以使用通配符匹配,例如 p:lang(*-CH)
将可以匹配 de-CH
的 p
元素。
.lang p:lang(de-DE) {
color: green;
}
.lang p:lang(*-CH) {
color: blue;
}
<div class="lang">
<p lang="de-DE-1996">de-DE-1996</p>
<p lang="de-CH">de-CH</p>
</div>
想解锁更多姿势就去看 The language pseudo-class 草案
The Hyperlink Pseudo-class——:any-link 伪类
:any-link
用于匹配带有 href
属性的超链接元素,例如 <a>
,<area>
,<link>
等带有 href
属性的元素。:-webkit-any-link
和 :-moz-any-link
是它的兼容性写法。
.link a:any-link {
color: red;
}
.link a:-webkit-any-link {
color: red;
}
.link a:-moz-any-link {
color: red;
}
<div class="link">
<a href="#">我是带有颜色的超链接</a>
</div>
想解锁更多姿势就去看 The Hyperlink Pseudo-class 草案
The contextual reference element pseudo-class——:scope
:scope
用于匹配当前作用域下的顶级元素。但是目前 <style scoped>
已经被移除——issue
<div class="scope">
<p>This paragraph is outside the scope.</p>
<div>
<style scoped>
:scope {
background-color: red;
}
p {
color: blue;
}
</style>
<p>This paragraph is inside the scope.</p>
</div>
</div>
以上代码,第二个 div
将会有红色背景,并且他的所有 <p>
子元素都将拥有蓝色文字。
Time-dimensional Pseudo-classes——:current(), :past(), :future()
我个人用 时间轴伪类
统一称呼 :current()
, :past()
, :future()
这三个伪类。:current()
匹配时间轴当前的元素,:past()
匹配 :current()
元素之前的元素,:future()
则匹配当前时间轴后的所有元素。这里说的时间轴指的是例如 WebVTT
。值得注意的是,规范中写道如果使用的时间轴并不是文档语言所规定的,那么 :past()
和 :future()
有可能分别匹配 :current()
元素的前面的兄弟元素和后面的兄弟元素。由于在 Chrome Canary 和 Safari TP 上都不支持这几个伪类,所以无法实验正确性。下面使用的例子是从这个网址摘过来的。
:current(p, span) {
background-color: yellow;
}
:past(p, span),
:future(p, span) {
background-color: gray;
}
<video controls preload="metadata">
<source src="https://html5demos.com/assets/dizzy.mp4" type="video/mp4" />
<source src="https://html5demos.com/assets/dizzy.webm" type="video/webm" />
<source src="https://html5demos.com/assets/dizzy.ogv" type="video/ogv" />
<track label="English" kind="subtitles" srclang="en" src="https://www.iandevlin.com/html5test/webvtt/upc-video-subtitles-en.vtt" default>
</video>
想解锁更多姿势就去看 Time-dimensional Pseudo-classes 草案
The Indeterminate-value Pseudo-class——:indeterminate
在 radio
和 checkbox
元素上一般有两种状态——选中
和 未选中
,但是有的时候的状态会是不确定状态,而 :indeterminate
就是匹配这种不确定状态的 radio
或 checkbox
。
:indeterminate + label {
background-color: gray;
}
<input type="radio" name="name" id="test">
<label for="test">未确定状态</label>
上面例子的 <label>
在 <input>
处于 indeterminate state
的时候,文字将会变为灰色。
想解锁更多姿势就去看 The Indeterminate-value Pseudo-class 草案
The default-option pseudo-class——:default
:default
匹配一组相似元素集合中的默认元素,例如 <form>
中有多个 <input>
,其中有一个是 <input type="submit">
,那么该元素将会被匹配。此外还有 <option>
也有默认元素。
.default .default-form :default {
background-color: gray;
}
<div class="default">
<form class="default-form" action="#" method="get">
<input type="submit" name="name" value="submit">
<input type="reset" name="name" value="reset">
</form>
</div>
想解锁更多姿势就去看 The default-option pseudo-class 草案
The validity pseudo-classes——:valid, :invalid
在 <input type="email">
中,如果我们输入了 abc123
,那么此时 :invalid
将会匹配该元素,假如我们输入 abc123@163.com
,那么此时 :valid
将会匹配该元素。这里要注意假如我们没有为 <input>
作约束,例如 <input type="text">
,那么它的任意输入将使元素既不会被 :valid
匹配,也不会被 :invalid
匹配。
.valid input:valid {
color: green;
}
.valid input:invalid {
color: red;
}
<div class="valid">
<input type="email" name="eamil_valid" value="abc@abc.com">
<input type="email" name="email_invalid" value="abc">
</div>
想解锁更多姿势就去看 The validity pseudo-classes 草案
The range pseudo-classes——:in-range, :out-of-range
:in-range
和 :out-of-range
只对有被条件约束的元素起作用,例如 <input type="number" min="1" value="1">
,如果输入数字小于 1,那么将会被 :out-of-range
匹配,反之则是被 :in-range
匹配。
.range input:in-range {
color: green;
}
.range input:out-of-range {
color: red;
}
<div class="range">
<input type="number" name="range" value="1" min="1" max="10">
</div>
想解锁更多姿势就去看 The range pseudo-classes 草案
The optionality pseudo-classes——:required, :optional
:required
和 :optional
分别匹配带有 required
标识的元素和不带 required
标识的元素。
.optionality input:required {
color: green;
}
.optionality input:optional {
color: red;
}
<div class="optionality">
<input type="text" name="required" value="required" required>
<input type="text" name="optional" value="optional">
</div>
想解锁更多姿势就去看 The optionality pseudo-classes 草案
The user-interaction pseudo-class——:user-error
:user-error
会匹配 :invalid
, :out-of-range
和没有任何值的 :required
元素,但是假如是初始化时就触发这三种错误,user-error
将不会匹配该元素,只有当用户和元素进行交互或者提交了该表单并且触发了这三种错误,:user-error
才会被触发。Chrome 和 Safari 可能尚未支持(也可能是我使用姿势不对,希望指正),所以无法验证正确性。
.user-error input:user-error {
color: red;
}
.user-error input:valid {
color: green;
}
<div class="user-error">
<input type="email" name="eamil_valid" value="abc@abc.com">
<input type="email" name="email_invalid" value="abc">
</div>
想解锁更多姿势就去看 The user-interaction pseudo-class 草案
The mutability pseudo-classes——:read-only, :read-write
:read-only
匹配不可被编辑的元素,:read-write
则匹配可被编辑的元素,例如 <input>
或者 contenteditable="true"
的元素。:-moz-read-only
和 :-moz-read-write
分别是他们的兼容性写法。
.mutability :read-only {
color: red;
}
.mutability :read-write {
color: green;
}
<div class="mutability">
<input type="text" name="read-write-input" value="read-write">
<p contenteditable="true">read-write-paragraph</p>
<p>read-only-paragraph</p>
</div>
想解锁更多姿势就去看 The mutability pseudo-classes 草案
The placeholder-shown pseudo-class——:placeholder-shown
:placeholder-shown
匹配 placeholder
文字显示时的 <input>
元素。::-webkit-input-placeholder
, ::-moz-placeholder
, :-ms-input-placeholder
分别是它在不同浏览器的兼容性写法。
.placeholder input:placeholder-shown {
color: green;
}
.placeholder input::-webkit-input-placeholder {
color: green;
}
.placeholder input::-moz-placeholder {
color: green;
}
.placeholder input:-ms-input-placeholder {
color: green;
}
<div class="placeholder">
<input type="text" name="placeholder" placeholder="placeholder is green">
</div>
想解锁更多姿势就去看 The placeholder-shown pseudo-class 草案
Grid-Structural Selectors
该特性将对例如 <table>
的栅格布局起作用。它包含 :column(selector)
, :nth-column(n)
和 :nth-last-column(n)
。目前浏览器都还未支持,无法实验正确性。
:column(selector)
:column(selector)
将匹配例如 <table>
中 带有 selector
类名的那一列的所有元素。
:column(.selected) {
color: green;
}
<table>
<col class="selected" />
<col class="blur" />
<col class="blur" />
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>D</td>
<td>E</td>
<td>F</td>
</tr>
<tr>
<td>G</td>
<td>H</td>
<td>I</td>
</tr>
</table>
在上面的例子中,A、D、G 都将是绿色的。
:nth-column(n) 和 :nth-last-column(n)
:nth-column(n)
匹配括号内 n
的计算值的某一列的元素,计算方式是从头开始计算,而 :nth-last-column(n)
则是从后开始计算。
:nth-column(2n) {
color: red;
}
:nth-last-column(3n) {
color: green;
}
<table>
<col class="selected" />
<col class="blur" />
<col class="blur" />
<tr>
<td>A</td>
<td>B</td>
<td>C</td>
</tr>
<tr>
<td>D</td>
<td>E</td>
<td>F</td>
</tr>
<tr>
<td>G</td>
<td>H</td>
<td>I</td>
</tr>
</table>
想解锁更多姿势就去看 Grid-Structural Selectors 草案
Tree-Structural pseudo-classes——:blank
Tree-Structural pseudo-classes 是 CSS3 中的规范,但在 CSS Selectors Level 4 中加入了 :blank
,它和 :empty
类似,区别在于 :empty
只能匹配没有任何内容的元素,而 :blank
可以匹配带有 spaces(空格)
, tabs(缩进符)
and segment breaks(段落过段)
内容的元素。
想解锁更多姿势就去看 :blank pseudo-class 草案
Combinators——>>
A >> B
匹配祖先元素为 A 的 B元素,其用法与 A B
一样,与 >
, +
, ~
用意一样,不过意义不同。
想解锁更多姿势就去看 Combinators 草案
上面的特性都已经存在 Working Draft 中,还有一些 Editor’s Draft 的特性,也顺带一提。
The Relational Pseudo-class——:has()
:has(selector)
匹配含有 某些规则
的元素。
/* 将匹配含有 img 子元素的 a 元素 */
a:has(> img)
/* 将匹配拥有 dt 兄弟元素的 dt 元素 */
dt:has(+ dt)
/* 将匹配不含有 h1、h2、h3、h4、h5、h6 元素的 section 元素 */
section:not(:has(h1, h2, h3, h4, h5, h6))
/* 和上面例子不同,下面交换了两个伪类的嵌套,表示匹配含有的不是 h1、h2、h3、h4、h5、h6 子元素的元素,区别在于这种写法要求必须含有一个子元素,而上面的写法可以不含有子元素也会被匹配 */
section:has(:not(h1, h2, h3, h4, h5, h6))
想解锁更多姿势就去看 The Relational Pseudo-class 草案
The Drag-and-Drop Pseudo-class——:drop, :drop()
:drop
和 :drop()
匹配可被放置拖动元素的目标元素,两者区别在于 :drop()
可以匹配一些规则,包括 active
, valid
, invalid
。active
会匹配可被放置的目标元素,valid
匹配放置的元素为合法元素的目标元素,invalid
反之。如果 :drop()
括号里没有任何过滤,那么将和 :drop
没有区别。
想解锁更多姿势就去看 The Drag-and-Drop Pseudo-class 草案