Skip to content

逻辑选择器

:is()

:is() CSS伪类函数将选择器列表作为参数,并选择该列表中任意一个选择器可以选择的元素

基础用法

当有多个共性样式时,以前可能会这样写

css
header p,
hover p,
footer p {
    color: red;
}

现在可以改写成

css
:is(header, main, footer) p {
    color: red;
}

不支持伪元素 ::after::before

不能写成

css
p:is(::before, ::after) {}

优先级

对于 :is() 选择器的优先级,不能把它们割裂开来看,它们是一个整体,优先级取决于选择器列表中优先级最高的选择器

有如下 html

html
<div>
    <p class="test__class" id="test__id">have id</p>
</div>
<div>
    <p class="test__class">not have id</p>
</div>

给带 .test__class 的元素,设置一个红色

js
div .test__class {
    color: red;
}

假如引入下面样式

css
div :is(p) {
    color: blue;
}

由于 div :is(p) 可以看成 div p,优先级是没有 div .test-class 高的,因此,被选中的文本的颜色是不会发生变化的

但是如果在添加一个 #test__id

css
div :is(p, #test__id) {
    color: blue;
}

按照猜想,带有 #text-id<p> 元素由于有了更高优先级的选择器,颜色将会变成 blue,而另外一个 div p 由于优先级不够高的问题,导致第一段文本依旧是 red

但,两端文本都变成 blue

这是因为 :is() 优先级取决于选择器列表中优先级最高的选择器

:where()

:where():is() 一样,将选择器列表作为其参数,并选择可以由该列表中的选择器之一选择的任何元素

css
header p,
hover p,
footer p {
    color: red;
}
css
:where(header, main, footer) p {
    color: red;
}

:is:where 的区别:优先级

:where() 的优先级总是为 0

引用上面例子

html
<div>
    <p class="test__class" id="test__id">have id</p>
</div>
<div>
    <p class="test__class">not have id</p>
</div>
css
div .test__class {
    color: red;
}

div :where(p, #test__id) {
    color: blue;
}

最后结果,两个文本都是 red,因为 :where 优先级为 0

:not()

匹配当前元素与括号里面的选择器不匹配的元素

可以级联

css
/* 不禁用,且不处于只读状态的 input 元素 */
input:not(:disabled):not(:read-only) {}

:has()

兼容性很差,只有高版本 safari 支持,还需要等待

:has 伪类接受一个选择器组作为参数,该参数相对于该元素的 :scope 至少匹配一个元素

:has 填补了在之前 CSS 选择器中,没有核心意义上真正的父选择器前兄弟选择器的空缺

父元素选择器

html
<div>
    <p>a</p>
</div>
<div>
    <p class="test__class">b</p>
</div>
css
div:has(.test__class) {
    border: 1px solid #000;
}

前兄弟选择器

html
<h1 class="h">h1</h1>
<h2 class="h">h2</h2>
css
.h:has(+ h2) {
    color: red;
}