这篇文章发布于 2019年07月28日,星期日,19:05,归类于 CSS相关。 阅读 31040 次, 今日 4 次 14 条评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=8808
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。
一、特别的你,特别的0优先级
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 class="read-only">
因为<input class="disabled">
虽然不会匹配input:not(.disabled),但是会匹配input:not(.read-only)
,导致出现了不希望出现的匹配效果。
这里,正确的书写方法应该是:
/* 正确的书写 */
input:not(.disabled):not(.read-only) {}
2. 全局否定的逻辑错误
例如我们希望除了<article>
标签下的<p>
元素的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
伪类是目前唯一一个可以大规模放心使用的逻辑伪类,非常有用,优点也很突出,大家可以多用用。
但是,其中也不乏一些会让人踩坑的地方,本文就介绍这几个大家可能会理解错误或使用错误的地方,至于其优点在那里,限于不是本文重点,以后有机会在详细介绍,总之,好用,大家要多用用。
好了,就说这么多。
小朋友又生病了,连续去了3天医院了,待会儿还要去医院挂水,不扯了,感谢阅读,欢迎分享。
本文为原创文章,欢迎分享,勿全文转载,如果内容你实在喜欢,可以加入收藏夹,永不过期,而且还会及时更新知识点以及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=8808
(本篇完)
- 巧用:is()或:where()伪类让scoped的style依然全局匹配 (0.814)
- 好奇心驱使下试验了chatGPT写CSS代码的能力 (0.525)
- CSS属性选择器驱动的过滤搜索技术 (0.225)
- CSS @supports开始支持selector选择器检测了 (0.225)
- CSS :not()伪类选择器已支持复杂参数 (0.225)
- IE7浏览器下CSS属性选择器二三事 (0.180)
- link rel=alternate网站换肤功能最佳实现 (0.180)
- 如何disabled禁用所有表单input输入框元素 (0.180)
- 告别pointer-events:none使用HTML inert属性真正禁用 (0.180)
- CSS :visited伪类选择器隐秘往事回忆录 (0.070)
- 常见纯CSS图标的代码分离与整理(持续更新) (RANDOM - 0.006)
大佬,:not()选择器能选中显示的元素吗?我有一组li,一些是隐藏一些是显示,我想选中显示的li的最后一个,我想通过:not():last-child来实现,但是:not()的括号里我不知道该写什么,在网上搜索了一圈也没找到答案。
有demo吗?你这样描述我也get不到精准的细节。
请教下,想实现高亮元素的功能,及想选择某个元素外的所有元素,将他们隐藏,直观的想法是用 :not(.selector) 选中其他元素然后隐藏,但这会让html和body也选中,最后是整个页面都被隐藏了,并不能达到效果,改成 body :not(.selector)这样也不行。想问下这种情况应该怎么办?
这些元素需要有特殊的类名、标签或属性,然后再:not()
本来还想试试双重否定变肯定,通过两个:not实现is,还是放弃了
大神请教个问题。希望可以看到我。先贴下代码:
css:.footer_cert a:first-child{
color:red
}
js: function getH () {
document.write(‘<a>你好</a>’)
}
html:
getH()
问题:a标签的样式加不上,如果不使用伪类,使用通用的class或者标签等都是可以加上的。
document.write不是可以引起整个文档重绘吗?DOM元素的添加或删除会引起回流,为什么单独这个伪类样式加不上呢?
大佬多注意身体啊
p {
margin: 0;
}
article p {
margin: 1em 0;
}
这里是不是写错了,不是为了让article p 的margin:0;
应该是这样才符合文章的意思吧:
p {
margin: 1em 0;
}
article p {
margin: 0;
}
sorry,我看错了
伪类选择器会节省加载时间吗?
没什么区别。
奇妙的css
大晚上的去医院,幸苦小张了。
祝小朋友早日康复!