CSS否定伪类:not()的正确认识

目录
文章目录隐藏
  1. 概述
  2. 一、优先级
  3. 不支持复杂选择器
  4. 容易搞混的否定逻辑关系
  5. 结束语

概述

CSS 否定伪类,:not(X),是以一个简单的以选择器 X 为参数的功能性标记函数。它匹配不符合参数选择器 X 描述的元素。X 不能包含另外一个否定选择器。

:not 伪类的优先级即为它参数选择器的优先级。:not 伪类不像其它伪类,它不会增加选择器的优先级。
CSS 否定伪类:not()的正确认识

一、优先级

CSS :not 伪类常见错误认知之一就是搞不清楚其优先级。

如果对所有 CSS 伪类的优先级(也就是我们常说的选择器权重)进行分类,你会发现总共只有两个级别,0 级和 10 级。

0 级指没有优先级;
1 级是标签选择器;
10 级是类选择器,属性选择器;
100 级是 ID 选择器。

伪类,伪类,既然带有“类”字,自然其优先级好类选择器一致。

但是,其中有个特殊,那就是逻辑伪类的优先级都是 0。例如::not(),:is(),:where()等。

逻辑伪类整个选择器语句的优先级是由括号里面内容决定的,不同的逻辑伪类规则不一样,其中:not()伪类的本身没有优先级,最终优先级是由括号里面的选择器决定的。

例如:

:not(.disabled) {}    /* 优先级等同于.disabled 选择器 */
:not(a) {}    /* 优先级等同于 a 选择器 */

不支持复杂选择器

:not()逻辑伪类出身很早,早到 IE9 浏览器都支持,不像现在的新出来的逻辑选择器,:not()伪类括号里面并不支持复杂的选择器(虽然新的规范已经让支持了,目前还没有浏览器跟进)。

例如,:not()伪类括号里面不能多个选择器:

:not(.disabled, .read-only) {}    /* 无效,不支持 */

正确写法为:

:not(.disabled), :not(.read-only) {}

例如,:not()伪类括号里面不支持选择器级联:

:not(a.disabled) {}    /* 无效,不支持 */

正确写法为:

:not(a):not(.disabled) {}

容易搞混的否定逻辑关系

这是本文的重点。

1. 连续否定的逻辑错误

例如,如果我们想要匹配既不包含.disabled 类名,又不包含.read-only 类名的<input>元素,我们的选择器该如何书写,很多人会使用下面的 CSS 代码:

input:not(.disabled),
input:not(.read-only) {}

乍一看好像没问题,实际上,上面的书写是大大的错误。

逗号分隔的选择器,表示的是“或”的关系,而不是“与”的关系。因此 input:not(.disabled), input:not(.read-only)表示的含义是:不包含.disabled 类名的<input>元素,或者不包含.read-only 类名的<input>元素。

最后导致的结果是.disabled 类名和.read-only 类名元素都会匹配。

例如:



因为<input class="disabled">虽然不会匹配 input:not(.disabled),但是会匹配 input:not(.read-only),导致出现了不希望出现的匹配效果。

这里,正确的书写方法应该是:

/* 正确的书写 */
input:not(.disabled):not(.read-only) {}

2. 全局否定的逻辑错误

例如我们希望除了

标签下的

元素的 margin 值都是 0,我们代码该怎么写。

很多人会这样书写:

:not(article) p {
    margin: 0;
}

看上去没有问题,实际上问题非常严重,:not(article) p 实际语义是,如果<p>元素的祖先元素的标签名不是 article,则 margin 值是 0。

其中就包括这样的场景:

<article>
    <section>
        <p>margin 此时也是 0!<p>
    </section>
</article>

此时,虽然<p>元素在<article>元素内,但是,由于同时也在<section>元素内,于是匹配了:not(article) p 这个选择器,导致出现意料之外的样式表现。

正确的书写应该是:

p {
    margin: 0;
}
article p {
    margin: 1em 0;
}

咦?不能使用:not 伪类实现吗?对的,在这种场景下,:not 伪类是无解的。

除非强制层级元素,也就是<p>元素是<article>的相邻子元素元素,此时我们可以使用下面 CSS 满足我们需求,不过限制很大,建议还是使用传统重置策略:

:not(article) > p {
    margin: 0;
}

结束语

:not 伪类是目前唯一一个可以大规模放心使用的逻辑伪类,非常有用,优点也很突出,大家可以多用用。

但是,其中也不乏一些会让人踩坑的地方,本文就介绍这几个大家可能会理解错误或使用错误的地方,至于其优点在那里,限于不是本文重点,以后有机会在详细介绍,总之,好用,大家要多用用。

「点点赞赏,手留余香」

7

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » CSS否定伪类:not()的正确认识

发表回复