likes
comments
collection
share

从:is()说起,开启CSS伪类第二集

作者站长头像
站长
· 阅读数 32

前情提要

为了丰富自己是知识体系(为了日更薅羊毛),我最近频繁翻阅MDN的文档,果然MDN文档常看常新。

最近翻到CSS部分,然后打开了伪类这一栏,好家伙,快60个了(包括实验中的)。

跳过常用的,还是很多。分批分期研究的话,我想三期应该是能够收官。

今天开启第二篇:《看着简单却有大用处的CSS伪类》。

伪类们

:is()

:is() 伪类可以匹配入参的选择器列表中,任意一个选择器可以选择的元素

:is() 伪类大有用途,我对它的评价是「短小精悍」。

实例:简化选择器

我要设置不同元素下的a元素和span元素样式,使用:is() 伪类之前的样式代码:

ol li,
ul li,
li a {
  color: red;
}
p a,
p span {
  color: blue;
}

使用:is() 伪类之后的样式代码:

:is(ol, ul) :is(li, a, span) {
  color: red;
}
:is(p) :is(a, span) {
  color: blue;
}

展示效果

从:is()说起,开启CSS伪类第二集

实例:框架中全局匹配

这个很实用,日常开发中会使用第三方UI组件,这个时候需要重置样式一般采用下面的方案:

Vue框架中使用 :deep() 伪类函数,React使用 :global()

其实:is()也可以实现。

当然这个应用场景不是我总结,是我看张鑫旭大佬的文章《巧用:is()或:where()伪类让scoped的style依然全局匹配》学到的。详细的方案和总结,可以看这篇文章。

:where()

:where()伪类接受选择器列表作为它的参数,将会选择所有能被该选择器列表中任何一条规则选中的元素。

看这个介绍是不是跟:is() 伪类很像。没错,两个伪类的语法和作用十分相似,区别就在于选择器的优先级。

:where() 的优先级总是为 0,但是 :is() 的优先级是由它的选择器列表中优先级最高的选择器决定的。

实例::where() 和 :is()对比

  • 两组div和p元素,内层都是span元素,根据class名进行区分,分别设置了:where() 和 :is()伪类。
  • 另外单独设置了p元素下span元素的颜色值与前面的伪类不同。
:is(div.is-div, p.is-p) span {
  color: red;
}
:where(div.where-div, p.where-p) span {
  color: blue;
}
p span {
  color: gray;
}
......
<div class="is-div"><span> :is()伪类值div元素下的span元素</span></div>
<p class="is-p"><span>:is()伪类值p元素下的span元素</span></p>
<div class="where-div"><span> :where()伪类值div元素下的span元素</span></div>
<p class="where-p"><span>:where()伪类值p元素下的span元素</span></p>

展示效果

通过展示效果可以发现,单独设置的样式覆盖了:where()伪类的样式,没有覆盖:is()伪类的样式。原因就是前面提到的:where() 的优先级总是为 0,所以样式可以被覆盖。

从:is()说起,开启CSS伪类第二集

:not()

如果想对某个结构元素设置样式,但是想排除这个结构元素下面的子元素应用该样式,可以使用:not() 伪类。

:not() 伪类的参数可以是一个或多个选择器。多个选择器以逗号分隔。同时选择器中不得包含另一个否定选择器或伪元素。

MDN中有一行提示引起我的注意:

:not() 伪类有许多怪异、技巧和意料之外的结果,你在使用它之前应该意识到这些。

都有哪些需要特别注意📢,且看我下面的实例。

实例:提高规则的优先级

.foo:not(.bar) 和 .foo会匹配相同的元素,但是具有两个class的选择器具有更高的优先级。

所以第一行的文字颜色是红色而不是蓝色。第二行文字是蓝色

.foo:not(.bar) {
  color: red;
}
.foo {
  color: blue;
}
......
<div class="foo">foo</div>
<div class="foo bar">foo和bar</div>

展示效果

从:is()说起,开启CSS伪类第二集

实例:同时否定多个选择器

:not(.foo, .bar)会否定样式为.foo或.bar的元素。

  • 将样式为.foo或.bar的元素设置文字颜色是蓝色;
  • :not(.foo, .bar)设置的文字颜色是红色。
.foo,
.bar {
  color: blue;
}
:not(.foo, .bar) {
  color: red;
}
......
<div>无样式设置</div>
<div class="foo">foo样式</div>
<div class="bar">bar样式</div>
<div class="foo bar">foo和bar样式</div>

展示效果

从:is()说起,开启CSS伪类第二集

实例:可以匹配html和body元素

  • body元素上设置文字颜色是蓝色;
  • :not(.foo, .bar)设置的文字颜色是红色。

但是看展示效果,文字颜色都是红色,因为:not(.foo) 将匹配任何非 .foo 的元素,包括 html元素 和 body元素。且前面提到,:not伪类会提升优先级,所以最终页面的文字颜色均为红色。

body {
  padding: 0;
  margin: 0;
  background: #fff;
  color: blue;
}
:not(.foo) {
  color: red;
}
......
<div>无样式设置</div>
<div class="foo">foo样式</div>
<div class="bar">bar样式</div>

展示效果

从:is()说起,开启CSS伪类第二集

未完待续

第二集的伪类分享就到这里了,这期主要介绍了:is()、:where()、:not(),每个伪类的使用实例也都尝试了一遍。虽然数量少,但是每个下面的内容不少,且都有大用处。

最大的收获就是,CSS能玩出花的技能又增加了。

我喜欢创作,每一幅作品都是我将想象用一只叫做“代码”的画笔,绘制而成。

当我寻找新的技术的时候,不是创意枯竭,而是我需要新的色彩。

而这个循序渐进的学习过程,虽然缓慢,但是积少成多、聚沙成塔。