初探CSS 选择器Level 4

如果看完了还不过瘾?想和作者深聊相关话题,可以点击这里向作者提问!

在开始聊CSS选择器Level 4(Selectors Level 4)之前,先要明确一个简单的概念。时至今日,在CSS的世界之中再不会有大版本的称谓,比如以前大家熟悉的CSS2.1、CSS3。现在的CSS都只会以CSS模块的版本来进行区分,比如我们今天要聊的CSS选择器,其最新版本就是:CSS Selectors Level 4。在CSS Selectors Level 4中为选择器增添了不少的新特性,当然这些新特性有的已得到浏览器的支持,有的只得到部分主流浏览器的支持。所以接下来,花点时间学习一下,以备后用。

:not()

否定伪类:not()是一个函数伪类,以选择器列表做为参数,它表示的元素不是由其参数表示的。:not()选择器可以用来做为判断的一个选择器,好比JavaScript中的非。其主要作用就是将符合规则的元素剔除,将样式规则应用于其他元素上。事实上,在CSS Selector Level 3就有:not()的身影,只不过当初的功能比较弱,比如:not(p)用来选择不是<p>的元素。但在新版本的中,其功能变得更为强大,可以应用更为复杂的规则,但是同样地不允许嵌套使用,比如:not(:not(...))

我们平时开发项目的时候,时常会碰到列表这样的效果,列表项之间有一个margin-bottom,而往往想在最后一项中不设置margin-bottom。比如像下图这样的效果:

往往我们借助伪类选择器:last-child来帮我实现,比如:

li{
    margin-bottom: 20px;
}

li:last-child {
    margin-bottom: 0;
}

如果我们使用:not()选择器,会变得更容易:

li:not(:last-child) {
    margin-bottom: 20px
}

上面的代码表示的意思就是:选中除最后一项li的所有li,并给其设置margin-bottom: 20px;

另外,:not()选择器还有一个提高CSS权重的小作用,比如div:not(span)div是同一个概念,但是明显的前者的优先级要更高。

浏览器的支持度:

:has()

关系伪类:has():not()选择器类似,也是一个函数伪类,不同的是:has()使用相对选择器列表作为参数。它表示一个元素,任何一个相对选择器(当将元素绝对化并将其赋值为:scope元素)至少匹配一个元素。

:has()伪类有点类似于jQuery中的.has()方法,简单来说就是用来匹配含有某些规则的元素。比如:

// 匹配含有`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)) {}

最后两个示例是:not():has()组合在一起使用的,但两者组合在一起所达到的意思却完全不一样。其中:not(:has(selector))匹配不含有selector选择元素的元素(有点绕,对应看上面示例描述),而:has(:not(selector))匹配含有的不是selector子元素的元素。两都主要区别在于,:has(:not(selector))写法必须要含有一个子元素,而:not(:has())可以不含有元素也会被匹配。

:matches()

:matches()同样是一个函数伪类,以选择器列表作为参数。主要用于匹配所述规则的元素,并应用相应的样式规则,选择该列表中任意一个选择器可以选择的元素。它可以让我们节省书写大量的 CSS 样式匹配规则,让我们从大量重复的规则书写中解放出来。

来看两个示例:

.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;
}

注意,许多浏览器通过一个更旧的伪类选择器:any()来替代:matches(),并且要带上对应的浏览器私有前缀,:-webkit-any():-moz-any(),其工作方式与:matches()完全相同,比如上面示例,我们可以改写成:

.matches :-webkit-any(span, div) :-webkit-any(span, div) {
    color: green;
}
.matches :-moz-any(span, div) :-moz-any(span, div) {
    color: green;
}

来看一个简单的示例:

示例中通过一行代码:

:matches(header, main, footer) p:hover {
    color: red;
    cursor: pointer;
}

就替代了:

header p:hover,
main p:hover,
footer p:hover {
    color: red;
    cursor: pointer;
}

如果你使用过CSS的处理器,就较好理解,它有点类似于CSS处理器中的嵌套规则。

有一点需要注意,:matches()不能嵌套工作,也不能和:not()配合在一起工作,比如下面的几个选择器,都将无法正常工作:

:matches(:not(...)) {}
:not(:matches(...)) {}
:matches(:matches(...)) {}

除此之外,在:matches()传递的选择器列表中也不允许一些组合选择器,比如~>+等。

浏览器支持度:

特别声明,matches()后面将会改变:is()

:something()

:something()被称为权重调整伪类,也是一个函数伪类,其语法和功能与:matches()类似。其不同之处是:something()伪类和它的任何参数都不影响选择器的权重,它的权重总是为0

对于在选择器中引入过滤器很有用,同时保持关联的样式声明易于重写。

下面是一个常见的例子:

a:not(:hover) {
    text-decoration: none;
}

nav a {
    /* 无效果 */
    text-decoration: underline;
}

如果我们使用:something()伪类选择器就可以达到作者期望的效果:

a:something(:not(:hover)) {
    text-decoration: none;
}

nav a {
    /* Works now! */
    text-decoration: underline;
}

未来的选择器可能会引入额外的参数来显式的设置伪类的权重。

:dir()

:dir()主要用于匹配符合某个方向性的元素,例如:dir(ltr):dir(rtl),其中ltrleft to right简写,表示从左向右,而rtlright to left,表示从右向左。使用:dir()匹配元素和使用[dir="ltr"][dir="rtl"]在某种程度上是一样的效果,其区别是[dir=""]无法匹配到没有显式声明dir的元素,但:dir()却可以匹配到由浏览器计算得到或者继承来的dir属性的元素。因此,如果我们有明确地对某个元素声明dir,那么属性选择器[dir=""]就可以匹配到对应的元素,但如果我们只单纯的从父元素继承来而的dir,就需要使用伪选择器:dir()来匹配。

[dir="ltr"] {
    color: green;
    border-color: green;
}

[dir="rtl"]{
    color: #f36;
    border-color: #f36;
}

body :dir(ltr) {
    color: orange;
    border: 2px solid orange;
}

支持的浏览器下看到的效果如下图:

浏览器支持度:

注意,dir是HTML元素的属性,对应的效果和CSS的direction属性一样。

:lang()

很多Web页面都会在html元素上显式的指定lang属性,比如小站默认指定的是zh-hans,如下图所示:

:lang()就可以用来匹配声明了lang="val"的元素,并且可以使用通配符匹配,例如html:lang(*-CH)将可以匹配de-CHhtml元素。

html:lang(de-DE) {
    color: green;
}
html:lang(*-CH) {
    color: blue;
}

:any-link:local-link

:any-link用于匹配带有href属性的元素,比如常见的<a><link>等元素。如果元素匹配:link:visited,则它匹配元素,并且与:matches(:link, :visited)等价。比如下面这个示例:

:link, :visited {
    color: #f36;
}

:matches(:link, :visited) {
    color: #f36;
}

也可以用:any-link来写:

:any-link {
    color: #f36;
}

:-webkit-an
剩余70%内容付费后可查看
* 请输入阅读码(忘记阅读码?

如需转载,烦请注明出处:https://www.w3cplus.com/css/css-selectors-level-4.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部