:has()是CSS Selectors Level 4规范中的关系选择器,支持Chrome 105+、Safari 15.4+、Firefox 121+,可基于子/兄弟元素状态反向选择父容器并应用样式,解决长期存在的“反向选择”难题。

CSS4 中没有 :has 伪类——它属于 CSS Selectors Level 4 规范,但早在 2023 年已正式进入 Chrome 105+、Safari 15.4+ 和 Firefox 121+ 的稳定支持阶段,无需前缀,可直接使用。它的核心价值是“父元素响应子/兄弟元素状态”,解决长期存在的“反向选择”难题。
为什么 :has() 能触发兄弟元素悬停联动
:has() 是关系选择器,允许你基于内部匹配条件“向上定位”父元素,再结合相邻兄弟选择符(如 +、~)或子选择符,实现状态传递。关键在于:它不改变 DOM 结构,只扩展了选择能力。
- 传统 CSS 无法从
.item:hover反向影响前面的.header,但.container:has(.item:hover)可以选中整个容器,进而控制其内部任意元素 - 必须用父级作为锚点:不能写
.item:has(+ .trigger)(语法非法),只能写.container:has(.item:hover) - 性能上无明显负担,现代浏览器已对
:has()做了优化,但避免嵌套过深(如:has(:has(:has(...))))
最简可行示例:悬停 item 时高亮同级 header
典型场景:卡片列表中,鼠标移到任一卡片,顶部分类标题同步变色。
<div class="section"> <h3 class="section-title">前端工具</h3> <div class="card">ESLint</div> <div class="card">Prettier</div> </div>
对应 CSS:
.section:has(.card:hover) .section-title {
color: #007bff;
text-decoration: underline;
}
- 注意:
.section-title必须是.section的后代(可嵌套多层),不能是上一个兄弟节点(否则需调整 HTML 结构) - 若想影响前一个兄弟(如
.section-title在.section外),必须把它们包进同一父容器,否则纯 CSS 无解 - Firefox 121+ 才支持
:has()中的伪类(如:hover),旧版仅支持元素匹配
:has() 配合 + 和 ~ 实现精确兄弟控制
当目标元素与触发元素处于同一层级且顺序固定时,可用 + 或 ~ 进一步缩小作用范围,避免误触。
<div class="group"> <button class="trigger">Hover me</button> <div class="tooltip">I'm visible on trigger hover</div> <div class="spacer"></div> </div>
只让紧邻的 .tooltip 显示(忽略 .spacer):
.group:has(.trigger:hover) .trigger + .tooltip {
opacity: 1;
visibility: visible;
}
-
+匹配**紧邻下一个兄弟**,~匹配**后续所有同类兄弟**,按需选用 - 不要写
.trigger:hover + .tooltip—— 这仍是正向选择,无法跨父级生效 - 如果
.tooltip不在.trigger同一父级下(比如在 body 底部),必须用 JavaScript;:has()无法跨树操作
兼容性兜底和常见失效原因
尽管主流浏览器已支持,但上线前仍需验证实际运行环境。以下问题最常导致 :has() 看似“不工作”:
- Chrome 版本低于 105、Safari 低于 15.4、Firefox 低于 121 —— 直接忽略该规则,不报错也不生效
- 写了
:has(.item:focus-within)却没给.item设tabindex,导致无法获得焦点,自然不触发 - 在 CSS-in-JS(如 styled-components)中未启用
:has支持,部分旧版解析器会直接丢弃含:has()的整条规则 - 伪类嵌套错误:写成
:has(:hover)(缺少选择器)或:has(*:hover)(星号不推荐,可读性差且某些浏览器解析异常)
真正难处理的是 DOM 层级断裂——一旦目标元素不在 :has() 所选父容器内,再怎么调选择器都没用。这时候别硬扛,该加 wrapper 就加,该交由 JS 处理就交,CSS 不是万能胶。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











