摘要
在 CSS 选择器大家族中新增了几个特殊的选择器:
:is()
:where()
:not()
:has()
:is()
选择器
:is()
CSS 伪类函数以选择器列表作为参数,并选择该列表中任意一个选择器可以选择的元素。
对于多个不同父容器的同个子元素的一些共性样式设置,可能会出现如下 CSS 代码:
.header div:hover,
.main div:hover,
.footer div:hover {
color: green;
cursor: pointer;
}
使用:is()
选择器,则上述代码可以被改写为:
:is(.header, .main, .footer) div:hover{
color: green;
cursor: pointer;
}
支持多层叠用
示例代码
<div>
<span>div > span</span>
</div>
<div>
<i>div > i</i>
</div>
<p>
<span>p > span</span>
</p>
<p>
<i>p > i</i>
</p>
<p>
<div>p > div</div>
</p>
<div>
<p>div > p</p>
</div>
我们希望 div 和 p 标签下的 span 和 i 标签的内容颜色为绿色
div span,
div i,
p span,
p i {
color: green;
}
使用:is()
选择器,代码可以简化为:
:is(div, p) :is(span, i) {
color: green;
}
如果我们希望这些元素是在 hover 或是 focus 状态下才改变字体颜色呢,普通 CSS 怎么写:
div span:hover,
div i:hover,
p span:hover,
p i:hover,
div span:focus,
div i:focus,
p span:focus,
p i:focus{
color: green;
}
使用:is()
选择器
:is(div, p) :is(span, i):is(:hover, :focus) {
color: green;
}
优先级
:is()
选择器前面说了只是一个简化的语法糖,所以它的优先级是遵循组合出的 CSS 的选择器的优先级,即ID -> 类 -> 元素
的优先级。
不能选择伪元素
:is()
不能选择伪元素,所以下面的代码是行不通的:
div:is(::after, ::before) {
display: block;
}
:where()
选择器
了解了 :is()
选择器,接下来我们来看下 :where()
选择器。它们两个之间具有很强的关联性。
示例代码
.header div:hover,
.main div:hover,
.footer div:hover {
color: green;
cursor: pointer;
}
使用:where()
选择器
:where(.header, .main, .footer) div:hover{
color: green;
cursor: pointer;
}
:is()
和 :where()
的区别
:is()
和 :where()
的区别在于::where()
的优先级总是 0。
除此之外,:is()
和 :where()
无任何差别。
<div>
<p class="demo-class">where & is</p>
</div>
div :is(p) {
color: red;
}
div :where(.demo-class) {
color: blue;
}
分析如下:
- 首先我们使用
:is()
选择器定义了 p 元素的文本颜色为红色 - 之后我们又使用
:where()
选择器使用类选择器定义了该 p 标签内的文本颜色为蓝色 - 结果是红色,很显然,
:where()
选择器没有生效。
:not()
选择器
:not()
用来匹配不符合一组选择器的元素。由于它的作用是防止特定的元素被选中,它也被称为_反选伪类
示例代码
<div>
<p class="demo-class1">where & is</p>
<p class="demo-class2">where & is</p>
<p class="demo-class3">where & is</p>
<p class="demo-class4">where & is</p>
<p class="demo-class5">where & is</p>
<p class="demo-class6">where & is</p>
</div>
div p:not(.demo-class1) {
color: red;
}
div 下的 p 标签文本的颜色设置为红色,除了那个 class 为 demo-class1
的 p 元素
而且,:not()
选择器还支持选择器列表为参数进行多选,考虑如下代码:
div p:not(.demo-class1, .demo-class2) {
color: red;
}
:has()
选择器
:has()
它的出现填补了 CSS 选择器不能选择父元素或是先前兄弟元素的空白。
示例代码
<p><span class="demo">1</span></p>
<p>2</p>
<p><i>3</i></p>
<p><span>4</span></p>
<p>
<span>
<span class="demo">5</span>
</span>
</p>
p:has(.demo, i) {
color: red;
}
- html 的结构为五个 p 标签,内部嵌套各不一样,注意最后一个 p 标签内部嵌套了两层
- css 代码表示,选择当前全部的 p 标签,
:has(.demo, i)
表示:这全部的 p 标签中我需要做下筛选,其中子元素含有demo
类的和含有 i 标签的筛选出来作为最后的值返回并设置文本颜色为红色。
被筛选出来的 p 标签应该是哪个?
- 第一个 p 标签有一个类为
demo
的 span 子元素,命中 - 第二个 p 标签没有子元素,不符合
- 第三个 p 标签有一个子元素为 i 标签,命中
- 第四个 p 标签有一个
span
标签子元素,但是没有demo
类,不符合 - 第五个 p 标签有一个嵌套的 span 标签,span 之下又嵌套了一个 span 标签,且这个 span 标签还有
demo
类,命中
总结下 :has()
的选择逻辑:
- 首先必须选择中一些可进行筛选的父级标签
- 之后
:has()
伪类可以搜索这些父级标签下的全部子元素(可以嵌套)或是兄弟元素,执行:has()
内部的选择器,筛选出符合条件的父级标签
总结
以上选择器有浏览器的版本兼容要求,请谨慎使用!