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);
}
}