2014年1月,我写了一篇文章:The Current Generation of CSS3 Selectors,这篇文章的目的是介绍一些CSS3
中新增的选择器。文中的选择器已经有了很多文档,并且也被大多数浏览器支持(包括IE9+)。
由于Selectors Level 4 specification 目前已是工作草案状态,并且Editor’s Draft of the same spec也在进行中(编辑草案通常被视为更有权威),未来的CSS
选择器看起来很明朗了,
这篇文章重点介绍没有在之前那篇文章中出现的新选择器。浏览器对这些新特性的支持并不乐观,所以我不建议在生产环境中使用这些新选择器。可以把这篇文章视为当规范进一步完善并且浏览器开始支持CSS4
的时候,它会带来什么影响。对于已经被支持的特性,我例举了demo。
:read-only 和 :read-write
这两个选择器是很简单的。任何可编辑的元素都是read-write
状态,反之,元素则是read-only
状态。看一下下面HTML:
CSS如下:
:read-only {
outline: solid 1px blue;
}
:read-write {
outline: solid 1px red;
}
对上述代码的分析如下:
- 开始的两个元素有蓝色的外轮廓,因为在HTML中,它们分别设置了
readonly
和disabled
。 - 第三个元素有红色的外轮廓,因为它是自然的可编辑状态(
read-write
),textarea
和所有的input
元素的默认行为是一样的。 - 最后一个元素(
div
)有红色的外轮廓,因为设置了contenteditable
属性。
在CSS
中,我很普通的使用了这两个选择器(没有将它们应用到任何元素),这也意味着所有的div
、span
和其它不可编辑元素会有红色的外轮廓,更像被用在特定的表单元素或有特定类选择器的元素。
:read-write
可能会在编辑草案中被移除。
浏览器对:read-only
和 :read-write
的支持:Chrome, Opera, Firefox, Safari.
注意:正如下面的demo显示,支持这些选择器的浏览器将设置了disabled
的input
元素定义为read-write
,然而根据规范,这是不正确的。
HTML:
Demo for :read-only
and :read-write
This input is "readonly":
This input is "disabled":
This input is normal:
This div is contenteditable
This div has nothing special.
Legend: Red outline: read-write; Blue outline: read-only
Demo by Louis Lazaris. See article.
CSS:
body {
line-height: 2em;
}
.c {
width: 600px;
margin: auto;
}
.p {
text-align: center;
font-size: .9em;
padding-top: 100px;
}
input:read-write, .ce:read-write, .ro:read-write {
outline: solid 1px red;
}
input:read-only, .ce:read-only, .ro:read-only {
outline: solid 1px blue;
}
View this code on codepen
默认选项伪类: :default
:default
伪类会匹配那些在一组相关的集合中作为默认选项的元素。例如,一个表单的默认提交按钮或一组单选按钮中被默认选中的按钮。
如下面的HTML片段显示的那样,可以有多个默认选项:
Fruits
Vegetables
Meats
Poultry
Nuts
Breads
将下面的CSS
应用到上面的HTML
:
input[type=checkbox]:default {
outline: solid 1px hotpink;
}
在这个案例中,所有有checked
属性的元素将呈现一个外轮廓的样式。
浏览器对:default
的支持:Chrome, Opera, Firefox, Safari.
在这个demo中,尽管默认选中的复选框应该有一个外轮廓,但是WebKit/Blink浏览器不会为默认选中的复选框应用轮廓,这看起来是一个Bug。Firefox能正确呈现。
HTML:
Demo for :default
Fruits
Vegetables
Meats
Poultry
Nuts
Breads
The items with a pink outline are in the "default" state. Chrome and Opera incorrectly fail to add the pink outline to the checkboxes.
Demo by Louis Lazaris. See article.
CSS:
body {
line-height: 2em;
}
.c {
width: 500px;
margin: auto;
}
.p {
text-align: center;
font-size: .9em;
padding-top: 100px;
}
input[type=checkbox]:default {
outline: solid 1px hotpink;
}
input:default {
outline: solid 1px hotpink;
}
View this code in codepen
有效性伪类: :valid 和 :invalid
这两个伪类在HTML表单中是非常有用的,它能给予用户在输入数据时视觉上的有效性,而这些本应该有JavaScript完成的。
看一个示例:
Email:
注意,这个字段期待被输入的数据时有效的邮件地址,可以这样做:
input[type=email]:invalid {
outline: red solid 1px;
}
input[type=email]:valid {
outline: lightgreen solid 1px;
}
根据上面的CSS
,用户没有输入之前,email字段将有红色的外轮廓,一旦用户输入合法的电子邮件,外轮廓会变成绿色。
用这些伪类可以很容易的在表单元素之前添加一个绿标记的伪元素(或其它类似的)来显示有效的字段数据。
需要注意的是:
- 有趣的是,有效性检测也能应用到
form
元素自身,来表明所有字段数据是有效的。 - 对
div
、p
等普通元素不起作用,因为这些元素没有什么方法来指定预期的数据格式。 - 普通且没有要求特定数据格式的
,默认是有效的,但如果设置了
require
属性却没有数据则是无效的。
浏览器对 :valid 和 :invalid支持:Chrome, Opera, Firefox, Safari, IE10+.
HTML:
Demo for :valid
and :invalid
Email:
Type an email address. The outline will change from red to green.
Demo by Louis Lazaris. See article.
CSS:
body {
line-height: 2em;
}
.c {
width: 500px;
margin: auto;
}
.p {
text-align: center;
font-size: .9em;
padding-top: 100px;
}
input[type=email]:invalid {
outline: red solid 2px;
}
input[type=email]:valid {
outline: lightgreen solid 2px;
}
View this code on codepen
范围伪类: :in-range 和 :out-of-range
这两个伪类对于那些要求数据介于一个指定范围的表单元素是非常有用的。你可以根据元素数据是否在指定范围之内来设计输入框样式。
因而HTML应该像这样子的:
注意默认值是"1993-01-01",不在数据允许的范围之内。你可以根据默认数据和输入的数据来动态地设计输入框样式,像这样:
input[type=date]:in-range {
outline: lightgreen solid 1px;
}
input[type=date]:out-of-range {
outline: red solid 1px;
}
需要注意的是:
- 能应用于
number
,datetime
,datetime-local
,month
,week
及其它允许范围的输入 - 支持
range
,但我不认为有一种方法能使range
元素的数据超出范围,这种情况下,使用这两个伪类的作用是非常有限的。 - 和其它伪类一样,此伪类仅作用在有能力定义可接受的数据范围的元素
浏览器对 :in-range 和 :out-of-range支持:Chrome, Opera, Firefox, Safari.
HTML:
Demo for :in-range
and :out-of-range
This date field expects a date between "1994-01-01" and "2015-03-01". Change to a valid date to see the outline switch from red to green.
Demo by Louis Lazaris. See article.
CSS:
body {
line-height: 2em;
}
.c {
width: 500px;
margin: auto;
}
.p {
text-align: center;
font-size: .9em;
padding-top: 100px;
}
input[type=date]:in-range {
outline: lightgreen solid 1px;
}
input[type=date]:out-of-range {
outline: red solid 1px;
}
View this code on codepen
可选择性伪类: :required 和 :optional
这两个伪类能让你基于表单字段是否需要填写来设计表单元素的样式。拿下面的HTML为例:
每个input
后面添加了一个空的span
元素,同时前面两个input
元素是比填的,第三个是非必填的。CSS如下:
input:required ~ .msg:after {
content: '*';
color: red;
}
input:optional ~ .msg:after {
content: '(optional)';
}
在这个示例中,我用兄弟选择器在紧跟每个必填字段的后面添加一个红色星号,非必填字段后添加 “optional”。
示例中使用了我额外添加的元素。如果你不喜欢,可以使用JavaScript动态添加或直接在input
元素上使用其他样式,但是不能对表单的input
元素使用伪类了,因而这种情况下你必须应用不同的样式。
浏览器对 :required 和 :optional的支持:所有浏览器.
HTML:
Demo for :required
and :optional
The red asterisks and "(optional)" text are added via CSS, based on the presence or absence of the required
attribute.
Demo by Louis Lazaris. See article.
CSS:
body {
line-height: 2em;
}
.c {
width: 500px;
margin: auto;
}
.p {
text-align: center;
font-size: .9em;
padding-top: 100px;
}
form div {
padding: 10px;
}
input:required ~ .msg:after {
content: '*';
color: red;
}
input:optional ~ .msg:after {
content: '(optional)';
}
View this code on codepen
不区分大小写的属性选择器: i
在CSS中,默认对属性的大小写是敏感的。例如,要选择所有href
属性的值以pdf结尾的元素,就不会选中其属性值以PDF结尾的。有一个很有用的新标记可以被添加到属性选择器中来覆盖这种行为:
a[href$="pdf" i] {
color: red;
}
现在属性选择器将选择所有href
链接到PDF文件的元素,不管.pdf扩展名是小写、大写还是混合写的。
浏览器对 i 的支持:Opera.
HTML:
Demo for case-insensitive attribute selectors
In non-supporting browsers, only the first link is red. In supporting browsers, all links are red.
Demo by Louis Lazaris. See article.
CSS:
body {
line-height: 2em;
}
.c {
width: 500px;
margin: auto;
}
.p {
text-align: center;
font-size: .9em;
padding-top: 100px;
}
form div {
padding: 10px;
}
a[href$="pdf"] {
color: red;
}
a[href$="pdf" i] {
color: red;
}
View this code on codepen
:blank伪类
[:blank]伪类和:empty
有点类似,在The Current Generation of CSS3 Selectors一文中介绍了empty
的用法。用empty
可以选择没有子元素的元素,不管其子元素是一个元素、文本节点还是空白节点,因此如果元素即使只包含一个空格,也不被认为是"empty"的。
然而,:blank
伪类将选择没有文本和其它子元素,包含空白的元素,它能包含空白、换行符等,这依然是有合格的。
HTML如下 :
第一个段落是完全的空元素,但第二个有一个空白字符。CSS如下:
p:blank {
outline: solid 1px red;
}
p:empty {
border: solid 1px green;
}
在这个示例中,对“blank”元素应用了红色的外轮廓,对 “empty”元素应用了绿色的边框。:empty
仅选择第一个段落,因为它是完全的空元素;:blank
则选择两个段落。
可能很难记住二者的差别,因为名字很相似,规范中也记录了一些问题,这个选择器可能会更名。
浏览器对 :blank的支持:没有浏览器支持。
Matches-any伪类: :matches()
:matches()
伪类是使选择分组更简洁的一种方式,当浏览器对其的支持情况得到改善时,是对规范很有用的一个补充。
在MDN的一个示例中,CSS如下:
section section h1, section article h1,
section aside h1, section nav h1,
article section h1, article article h1,
article aside h1, article nav h1,
aside section h1, aside article h1,
aside aside h1, aside nav h1,
nav section h1, nav article h1,
nav aside h1, nav nav h1, {
font-size: 20px;
}
用:matches()
,能将其简化:
:matches(section, article, aside, nav)
:matches(section, article, aside, nav) h1 {
font-size: 20px;
}
简化的版本可以解释为:对这四个元素,如果h1
在任意一个之内,并在任何相同的四个元素之内,则应用后面的规则。
需要注意的是:
- 以往的规范中是使用
:any
,需要添加-moz-
和-webkit-
私有前缀。 - 正如CSS-Tricks指出的,原则同选择器在预处理器中的嵌套规则。
- 该选择器的参数必须是一个”简单选择器“(不能是一个伪元素;除了子节点,不能使用连接符)
浏览器对 :matches()的支持:没有浏览器支持。但WebKit/Blink和Mozilla有等效的渲染选择。
相关伪类: :has()
:has()
伪类类似于JQuery中的.has()
方法,但前者有更广泛的能力。看一个示例就清楚了。注意代码中的注释,它解释了每一个示例选择什么元素。
/* Section elements that contain a footer */
section:has(footer) {
background: #ccc;
}
/* Any element containing a p element with a class of "alert" */
:has(p.alert) {
background-color: red;
}
/* img element with paragraph immediately following. */
img:has(+p) {
color: red;
}
/* list item with ul as a direct child */
li:has(> ul) {
color: red;
}
注意,:has()
存在编辑草案中而不是工作草案中;也正如Ralph在评论中指出的那样,这个选择器仅能通过JavaScript才可用(类似querySelectorAll
),而不是CSS。规范说明
浏览器对 :has()的支持:没有浏览器支持。
超链接伪类: :any-link
:any-link选择器是为任何具有href
属性指定样式的快捷方式,包括a
、area
和link
元素等,也能按照下面的方式使用:
:link, :visited {
color: #555;
}
作为代替,应该这样写:
:any-link {
color: #555;
}
需要注意的是,在工作草案中有一个:local-link
伪类,已经在编辑草案中被移除。
浏览器对 :any-link的支持:Chrome, Opera, 和Firefox(需要私有前缀)
输入焦点伪类: :focus-within
这是一个有趣的选择器,我可以明确地看到它是有用的。:focus-within不仅会选择获得焦点的元素,还会选择其父元素。
示例的HTML:
CSS如下:
input:focus-within {
outline: yellow solid 1px;
}
这不仅会导致获得焦点的input
元素有黄色的外轮廓,其父元素div
也有同样的外轮廓。
浏览器对 :focus-within的支持:没有浏览器支持。
拖放伪类: :drop 和 :drop()
在APPs中,拖放是很基础但又重要的功能。这两个选择器在改善用户体验上是很有价值的。:drop
选择器可以设置放置区样式(将要防止被拖动元素的地方),元素在用户的拖动期间是可放置的。
.spot {
background: #ccc;
}
.spot:drop {
background: hotpink;
}
用户没有拖动时,.spot
元素会有一个灰色背景;但当用户开始拖动.spot
元素时,其背景色会改变,直到元素被放下。
:drop()
的值为下列中的一个或多个关键字:
-
active
:为被拖动的元素显示当前的放置目标 -
valid
:显示与被拖动元素相关联的放置目标是否有效 -
invalid
:和前一个相反,如果与被拖动元素相关联的放置目标无效则为其应用样式
应用多关键字将让事情更具体,如果没有给予参数,其行为和:drop
一样。
注意:
- 工作草案规范有一组完全不同与此的伪类,因此这些选择器仍在变化中
-
drop()
是有"危险的",有可能被移除
浏览器对 :drop 和 :drop()的支持:没有浏览器支持
提名奖
除了上面提到的,还有一些新特性我不打算细讲,但也值得简单提一下:
* 列连接符(||
):用于定义table和grid中的列和单元格之间的关系
* :nth-column()
和:nth-last-column()
伪类用于指定table和grid中的特定列
* attr()
:属性节点选择器,是第一个非元素选择器
* 后代选择器由>>
代替(而不仅是一个空格字符)
* :user-error
伪类:为用户输入的数据不正确的文本框设置样式
* @namespace
:定义命名空间
* :dir()
伪类:根据方向来选择元素(如ltr
)
* :scope
伪类:为选择元素提供一个作用域或引用点
* :current
, :past
, 和 :future
伪类:定义目标元素在时间进程上的样式,如一个视频字幕。
* :placeholder-shown
伪类:定义表单元素中placeholder值不为空的input元素的样式
结束语和更多信息
正如之前提到的,这些功能非常新,并没有被很好的支持,仅展示了浏览器支持的信息和demos。
为了跟上进展,这里有一些关于CSS 4的资源:
- Selectors Level 4 Working Draft
- Selectors Level 4 Editor’s Draft
- CSS4 Rocks
- CSS4-Selectors
- Selectors Test
译文出处:http://www.ido321.com/1590.html
本文根据@Louis Lazaris的《The Future Generation of CSS Selectors: Level 4》所译,整个译文带有我自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://www.sitepoint.com/future-generation-css-selectors-level-4/