:is()和:where()核心区别在于特异性::is()取括号内最高权重选择器的权重,适合需继承父级权重的合并场景;:where()恒为0-0-0权重,专用于零干扰重置,默认样式或设计系统基底。

:is() 和 :where() 解决选择器重复问题
这两个伪类不是功能新增,而是语法糖级优化,核心价值是减少冗余、控制特异性。你写 :is(header, main, footer) p,等价于手写三个独立选择器,但更短、更易维护。
关键区别在特异性::is() 的权重由它内部最高权重的选择器决定(比如 :is(.foo, #bar) 权重 = #bar 的权重);而 :where() 内部所有选择器权重归零,整个选择器特异性为 0 —— 这意味着它几乎不会和其它规则打架,特别适合重置或默认样式。
- 用
:where()写全局按钮默认样式,后续加.primary类就能轻松覆盖 -
:is()更适合需要“继承父级权重”的场景,比如统一设置不同容器下的标题样式 - 两者都支持嵌套,例如
:is(:where(header, main) h1, footer h2)是合法的(但别过度嵌套,可读性会崩) - 无效选择器(如
:is(.valid, .invalid-unknown-class))会被忽略,整条规则仍生效 ——:where()尤其擅长这点
:has() 实现真正的“父元素选择”
这是 Level 4 中真正突破性的能力:首次允许 CSS 根据子元素状态反向影响父元素。过去必须靠 JS 或改 HTML 结构才能做到的事,现在一行 CSS 就能搞定。
典型用法是表单校验反馈、折叠菜单状态、卡片悬停高亮等。例如 form:has(input:invalid) 可直接给整个表单加红边框;article:has(.featured) 能给含特定 class 的文章加背景标识。
- 注意浏览器兼容性:Chrome 105+、Firefox 119+、Safari 15.4+ 支持,Edge 同 Chrome
- 不能在
:has()内部使用伪元素(如::before)或某些伪类(如:focus-within) - 性能敏感:避免在深层 DOM 或高频交互区域滥用,
:has(> div > span:last-child)比:has(.error)开销大得多 - 不支持在
@keyframes或属性选择器中使用
:not() 多参数与语义增强
旧版 :not() 只接受单个简单选择器,Level 4 允许传入逗号分隔的选择器列表,语义更接近“排除这些全部”,而不是“逐个 not”。
以前要写三行:div:not(.left):not(.right):not(.top);现在直接 div:not(.left, .right, .top)。不仅简洁,逻辑也更清晰 —— 它表示“只要匹配其中任意一个,就不选中”,而非嵌套否定。
- 这个写法在 Sass/Less 编译后可能出错,建议只在原生 CSS 环境中使用
- 仍不支持复杂选择器(如
:not(div p)),只能是简单选择器或属性选择器组合 - 和
:is()类似,:not()内部无效选择器会被跳过,不影响整条规则
:focus-visible 和 :focus-within 的实际落地点
它们不是 Level 4 新增,但 Level 4 明确规范并推动了普及。真正价值不在“能不能用”,而在“该不该用”和“怎么用对”。
:focus-visible 是解决“鼠标点击时意外出现焦点环”的关键:它只在键盘聚焦时触发,配合 :focus 可实现精准的可访问性反馈;:focus-within 则让整个容器响应子元素聚焦(比如表单域获得焦点时高亮整个卡片)。
- 不要用
:focus替代:focus-visible做键盘焦点样式,否则鼠标用户会看到干扰性轮廓 -
:focus-within在contenteditable区域、嵌套表单、动态加载内容中特别有用 - 部分旧版 Safari 对
:focus-visible支持不完整,需加-webkit-focus-ring-color回退
真正容易被忽略的是特异性控制 —— :where() 看似只是语法简化,但它让样式层叠关系变得可预测;而 :has() 虽强大,但它的计算成本藏在渲染引擎里,上线前必须实测滚动和交互帧率。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











