CSS `:has()` 实战指南:让 CSS 拥有“if 逻辑”

🔮 CSS :has() 实战指南:让 CSS 拥有"if 逻辑"

你是否经常写这样的 JS:

js 复制代码
if (element.querySelector('input:checked')) {
  element.classList.add('active');
}

现在,只需要用 :has(),你就能让 CSS 自己完成判断。


🧠 什么是 :has()

:has() 是一个关系伪类选择器,允许你根据子元素或后代元素的状态,来影响父元素的样式。

基本语法

css 复制代码
.parent:has(.child) {
  background: lightyellow;
}

📌 含有 .child.parent 会被选中。


✅ 实战一:表单错误状态

html 复制代码
<div class="form-item">
  <input type="text" required>
  <span class="error">必填项</span>
</div>
css 复制代码
.form-item:has(input:invalid) {
  border: 1px solid red;
}

.form-item:has(input:valid) {
  border: 1px solid green;
}

✅ 父容器会根据 input 的校验状态自动改变样式,无需 JS。


🧪 实战二:卡片 Hover 触发内部内容变化

html 复制代码
<div class="card">
  <button>操作</button>
</div>
css 复制代码
.card:has(:hover) {
  box-shadow: 0 2px 10px rgba(0,0,0,0.15);
}

📌 当 .card 内任何子元素 hover 时,整个卡片都会响应。


🧪 实战三:替代 JS 的下拉菜单展开

html 复制代码
<nav class="menu">
  <details>
    <summary>更多选项</summary>
    <ul>
      <li>设置</li>
      <li>帮助</li>
    </ul>
  </details>
</nav>
css 复制代码
.menu:has(details[open]) {
  background: #f0f9ff;
}

✅ 当 <details> 展开时,父级菜单会自动改变背景,完全不需要写 JS。


🌟 高级技巧

  1. 与否定逻辑结合

    css 复制代码
    .list:has(:not(li)) {
      background: #fee2e2; /* 如果列表为空,标记 */
    }
  2. 与交互伪类结合

    css 复制代码
    .card:has(button:focus) {
      outline: 2px solid blue;
    }
  3. 条件式布局控制

    css 复制代码
    .grid:has(.wide) {
      grid-template-columns: 2fr 1fr;
    }

🌐 浏览器支持(2025)

浏览器 支持情况
Chrome 105+
Edge 105+
Safari 15.4+
Firefox ⚠️ 实验支持(需开启 flag)

📌 大多数现代浏览器已经支持,Firefox 也即将跟进。


⚠️ 注意事项

  • 过度使用 :has() 可能带来性能问题(因为需要浏览器反向查询 DOM)
  • 尽量用在 UI 交互和组件样式上,而不是大规模列表匹配
  • Firefox 用户需注意兼容性,可提供 JS fallback

✨ 一句话总结

:has() 是让 CSS 更加"智能"的关键一步,它让样式具备逻辑判断能力,能大幅减少 JS 样式控制逻辑,是现代 CSS 架构中不可或缺的新利器。

相关推荐
用户0595401744615 小时前
把AI聊天机器人记忆存储测试从3小时压到5分钟,我用Pytest + Docker搭了一套自动化回归
前端·css
STU学生网页设计2 天前
大一学生作品《前端框架开发技术》 期末网页制作 HTML+CSS+JavaScript 个人主页网页设计实例
css·前端框架·html
用户059540174462 天前
大模型长记忆评测踩坑实录:2000条错位记忆,让我排查了整整3小时
前端·css
用户059540174463 天前
LangChain Memory 踩坑实录:10种异常场景差点搞崩生产,我们写了一套自动化测试保命
前端·css
用户059540174463 天前
Redis缓存回滚踩坑实录:一个配置失误,让我在凌晨3点丢了3000条数据
前端·css
এ慕ོ冬℘゜3 天前
纯 CSS 实现自定义 Switch 开关(商品上下架滑块)
前端·css
并不喜欢吃鱼4 天前
二.前端web开发:零基础吃透 CSS 核心知识
前端·css
思码梁田4 天前
CSS display 属性:从元素类型转换到隐藏元素的实用指南
前端·css·display·inline·block·none·inline-block
weipt4 天前
springboot项目运行的几种方式
javascript·css·html
用户059540174464 天前
把AI对话记忆存储测试从手工改成Playwright+pytest,覆盖率从20%提到96%,回归时间缩短90%
前端·css