CSS选择器 :is()、:where()、:not()、:has()

摘要

在 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()内部的选择器,筛选出符合条件的父级标签

总结

以上选择器有浏览器的版本兼容要求,请谨慎使用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zqwang888

一毛不嫌少,一块不嫌多!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值