#书摘 #css #前端
《CSS 选择器世界》 任意匹配伪类:
1.
先讲解
:is()伪类的一大作用是简化选择器。例如,平时开发中经常会遇到类似下面的CSS代码:
此时就可以使用:is()伪类进行简化:
这种简化只是一维的,:is()伪类的优势并不明显,但如果选择器是交叉组合的,:is()伪类就大放异彩了。例如,有序列表和无序列表可以相互嵌套,假设有两层嵌套,则最里面的
如果使用:is()伪类进行简化,则只有下面这几行代码:
2.
按道理讲,下面两行CSS语句中的选择器所匹配的元素是没有任何区别的,因为此时:is()伪类仅仅是一个无关紧要的语法糖,既不影响选择器的优先级,也不影响匹配的规则:
如果是在常规的开发场景中,确实如此,但要是在Vue或者React等成熟的框架中,则情况就会不同,可以利用这种特性让我们的开发变得更顺畅。
以Vue框架为例,在Vue框架中,无论是构建模块还是组件,都会使用设置了scoped属性的样式,目的是让CSS私有,避免和外部CSS发生冲突。例如:
此时框架会给类名.logo创建随机的属性选择器,这样可以确保.logo匹配的元素在当前Vue模块中是唯一的。
但是当我们需要匹配的元素是动态生成的时候(业务逻辑插入或者第三方组件),这种给类名添加随机属性选择器的特性可能会导致元素无法匹配。例如运行下面这段JavaScript代码:
此时插入的
如果此时希望可以匹配这个

虽然:is()伪类因这一特性在意想不到的地方发挥着作用,但其还是有令人遗憾的地方,尤其是不支持伪元素这一点::is()伪类并不支持伪元素,例如:is(::before, ::after)是不合法的,这是个巨大的遗憾。
目前现代浏览器已经全面支持:is()伪类,大家可以在一些内部项目中大胆使用。
https://memo.cosine.ren/m/362
《CSS 选择器世界》 任意匹配伪类:
is()
:is()
伪类可以把括号中的选择器依次分配出去,这对于复杂的有很多逗号分隔的选择器或者浏览器可能不支持的选择器非常有用。
:is()
伪类本身的优先级为0,整个选择器的优先级是由:is()伪类里参数优先级最高的那个选择器决定的。例如: :is(#article, .section) p {}
优先级等同于 #article p
。这是由参数中优先级最高的选择器决定的。1.
:is()
伪类的语法和两大作用先讲解
:is()`伪类的语法。和 :
not()` 伪类不同,`:is()` 伪类的参数从一开始就支持复杂选择器或复杂选择器列表。例如,下面的写法都是合法的:
/* 简单选择器 */
:is(article) p {}
/* 简单选择器列表 */
:is(article, section) p {}
/* 复杂选择器 */
:is(.article[class], section) p {}
/* 带逻辑伪类的复杂选择器 */
.some-class:is(article:not([id]), section) p {}
:is()伪类的一大作用是简化选择器。例如,平时开发中经常会遇到类似下面的CSS代码:
.cs-avatar-a > img,
.cs-avatar-b > img,
.cs-avatar-c > img,
.cs-avatar-d > img {
display: block;
width: 100%; height: 100%;
border-radius: 50%;
}
此时就可以使用:is()伪类进行简化:
:is(.cs-avatar-a, .cs-avatar-b, .cs-avatar-c, .cs-avatar-d) > img {
display: block;
width: 100%; height: 100%;
border-radius: 50%;
}
这种简化只是一维的,:is()伪类的优势并不明显,但如果选择器是交叉组合的,:is()伪类就大放异彩了。例如,有序列表和无序列表可以相互嵌套,假设有两层嵌套,则最里面的
<li>
元素存在下面4种可能的情况:
ol ol li,
ol ul li,
ul ul li,
ul ol li {
margin-left: 2em;
}
如果使用:is()伪类进行简化,则只有下面这几行代码:
css
:is(ol, ul) :is(ol, ul) li {
margin-left: 2em;
}
2.
:is()
伪类在Vue等框架中的妙用按道理讲,下面两行CSS语句中的选择器所匹配的元素是没有任何区别的,因为此时:is()伪类仅仅是一个无关紧要的语法糖,既不影响选择器的优先级,也不影响匹配的规则:
.box .some-class {}
.box :is(.some-class) {}
如果是在常规的开发场景中,确实如此,但要是在Vue或者React等成熟的框架中,则情况就会不同,可以利用这种特性让我们的开发变得更顺畅。
以Vue框架为例,在Vue框架中,无论是构建模块还是组件,都会使用设置了scoped属性的样式,目的是让CSS私有,避免和外部CSS发生冲突。例如:
<style scoped>
.logo {
height: 6em;
padding: 1.5em;
}
</style>
此时框架会给类名.logo创建随机的属性选择器,这样可以确保.logo匹配的元素在当前Vue模块中是唯一的。
但是当我们需要匹配的元素是动态生成的时候(业务逻辑插入或者第三方组件),这种给类名添加随机属性选择器的特性可能会导致元素无法匹配。例如运行下面这段JavaScript代码:
const html = ’<img src=”/vite.svg“ class=”logo“ />‘
const app = document.getElementById(’app‘)
app.insertAdjacentHTML(’afterbegin‘, html)
此时插入的
<img>
元素是不会被框架添加随机属性值的(如图9-3所示),而 <style>
元素中类名却自动添加了属性选择器,导致样式无法匹配。如果此时希望可以匹配这个
<img>
元素,同时CSS代码又要写在设置了scoped属性的 <style>
元素中,该怎么办?除Vue框架内置的:deep()语法外,我们还可以使用:is()伪类。不知是出于什么考虑,所有:is()伪类中的选择器在Vue框架中都是不会添加随机属性选择器的(:where()伪类也有此特性),因此,我们可以利用这个特性,让设置了scoped属性的 <style>
元素中的CSS无属性匹配。例如,CSS代码可以这样书写:
<style scoped>
* > :is(.logo) {
height: 6em;
padding: 1.5em;
}
</style>
此时,CSS代码中的.logo选择器就是干干净净的类选择器,如图9-4所示,此时,哪怕页面中的HTML元素没有被组件添加随机属性值,也能被匹配了。
虽然:is()伪类因这一特性在意想不到的地方发挥着作用,但其还是有令人遗憾的地方,尤其是不支持伪元素这一点::is()伪类并不支持伪元素,例如:is(::before, ::after)是不合法的,这是个巨大的遗憾。
目前现代浏览器已经全面支持:is()伪类,大家可以在一些内部项目中大胆使用。
https://memo.cosine.ren/m/362