css4并不存在,:has()和:not()均属css selectors level 4规范;:has()是新增父选择器,仅chromium105+和safari15.4+支持且有语法限制;:not()在level 4中支持复合选择器,已获主流浏览器完整支持。

CSS4 并不存在,:has() 和 :not() 都是 CSS Selectors Level 4 规范里的特性
很多人说“CSS4”,其实官方没有这个命名——W3C 的规范叫 CSS Selectors Level 4(选择器第四级),它不是独立于 CSS3 的新版本,而是对已有选择器能力的扩展。其中 :has() 是 Level 4 新增的、真正意义上的“父选择器”能力;而 :not() 虽然早在 CSS3 就存在,但 Level 4 极大放宽了它的限制,现在能嵌套复杂选择器了。
:has() 怎么用?哪些浏览器支持?为什么别在关键路径上依赖它
:has() 允许你基于后代/兄弟元素的状态反向影响祖先元素,比如 article:has(> .featured) 匹配含有直接子元素 .featured 的 article。它解决了长期缺失的“父选择器”需求,但有硬性约束:
- 不能出现在选择器开头以外的位置(即不能写成
div :has(span),必须是div:has(span)) - 不能包含伪元素(如
:before)、:hover等交互伪类,也不能用:has(:has(...))嵌套 - 目前仅 Chromium 105+(Chrome / Edge / Opera)、Safari 15.4+ 支持;Firefox 仍为实验性(需
layout.css.has-selector.enabled手动开启) - 性能敏感:浏览器需回溯 DOM 树判断条件,大规模使用可能触发重排或拖慢样式计算
:not() 在 Level 4 里到底放宽了什么?和旧版最大区别在哪
旧版 :not() 只允许单个简单选择器,比如 :not(.disabled) 或 :not(div),但不能写 :not(.foo.bar) 或 :not(a[href])。Level 4 解除了这个限制,现在可以传入任意复合选择器:
-
button:not(:disabled, [data-pending])—— 同时排除多个状态 -
p:not(:first-of-type, :last-of-type)—— 排除首尾段落 -
input:not([type="hidden"]):not([type="submit"])—— 多属性组合过滤
注意::not() 内部依然不能包含 :has(),也不能出现伪元素;且所有现代浏览器(Chrome 120+、Firefox 120+、Safari 16.4+)均已完整支持 Level 4 版本的 :not()。
实际项目中该不该立刻用 :has()?替代方案有哪些
除非目标用户明确集中在新版 Chrome/Safari,否则不建议用 :has() 实现核心布局或可访问性逻辑。它目前缺乏降级保障,CSS 无法像 JS 那样优雅 fallback。常见替代思路包括:
- 用 JS 动态添加 class(例如监听子元素变化后给父元素加
has-featured) - 重构 HTML 结构,把判断逻辑前移到父容器(如服务端/构建时注入
data-has-featured属性) - 用相邻兄弟选择器 +
:has()的近似效果模拟(例如.trigger + .target:has(~ .condition),但适用场景极窄)
真正容易被忽略的是:即使浏览器支持 :has(),它在媒体查询、@container 查询或 Shadow DOM 中的行为仍有未对齐的实现差异,上线前务必在真实设备上验证渲染一致性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











