CSS 伪类 :has 选择器父元素选择终于有了

FreeGuideOnline 最新 2026-07-05
邮箱
```
/* 当输入框获得焦点时,高亮整个表单组 */
.form-group:has(input:focus) {
  outline: 2px solid #4a90e2;
  background-color: #eef6ff;
}

/* 当输入框无效且被触碰时,呈现错误状态 */
.form-group:has(input:invalid:not(:placeholder-shown)) {
  border-left: 4px solid red;
  background-color: #fff5f5;
}

这样无需额外类名,完全由状态驱动的组件样式变得异常简单。

实用场景三:卡片布局的兄弟联动

:has() 还能选择相邻兄弟或兄弟组合,实现布局中的联动效果。

假设有一组卡片,当用户将鼠标悬停在某张卡片上时,我们希望前面的兄弟卡片也呈现一种淡化效果(创建焦点突出)。利用 :has() 我们可以选择到被悬停卡片后面的所有兄弟元素。

/* 悬停在一张卡片上时,其后面的卡片透明度降低 */
.card:hover ~ .card {
  opacity: 0.5;
}

/* 但前面的兄弟就无法直接用一般选择器选中,这时候 :has() 可以帮上忙 */
/* 选择拥有一个被悬停的后续兄弟的卡片 */
.card:has(~ .card:hover) {
  opacity: 0.5;
}

结合起来,就能实现除了悬停卡片外其他所有卡片都淡出的效果,这曾经需要 JavaScript 才能优雅完成。

实用场景四:导航菜单中的当前项高亮父级

在多级菜单中,如果子菜单项处于激活状态,通常也希望其父级菜单项保持高亮。:has() 可以轻松追溯祖先样式。

/* 当子菜单中有 .current 类时,父级 <li> 也保持激活样式 */
.nav li:has(.current) {
  background-color: #f0f0f0;
  font-weight: bold;
}

浏览器兼容性与渐进增强

截至 2024 年底,:has() 已获得所有现代浏览器的支持,包括 Chrome、Edge、Firefox、Safari 以及部分移动端浏览器。对于尚未支持的旧版浏览器,可以采用特性检测或渐进增强策略:

  • 核心功能不依赖 :has(),仅将其作为增强体验。
  • 使用 @supports 规则包裹样式,确保安全。
@supports selector(:has(*)) {
  .card:has(img) {
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  }
}