选择器组合实战
多个现代选择器组合使用的复杂案例
组合选择器的威力
单独使用现代选择器已经很强大,但当我们将 :has()、:is()、:where()、
:not() 等选择器组合使用时,可以实现更加复杂和智能的样式控制。
本页面展示了 4 个真实的复杂案例,演示如何通过组合多个现代选择器来解决实际项目中的样式需求。 这些案例涵盖了表格、表单、布局和导航等常见场景。
- 响应式表格 - 根据数据状态和选中状态动态调整表格样式
- 动态表单验证 - 组合多个选择器实现复杂的表单验证逻辑
- 条件样式布局 - 根据内容存在与否自动调整布局
- 智能导航 - 多级导航的自动状态管理
案例 1: 响应式表格样式
使用 :has() 和 :not() 组合,根据表格行的数据状态和选中状态,
动态显示批量操作按钮、高亮错误行、显示空状态提示。
| 用户名 | 邮箱 | 状态 | 积分 | |
|---|---|---|---|---|
| 张三 | zhangsan@example.com | 正常 | 1250 | |
| 李四 | invalid-email | 正常 | 890 | |
| 王五 | wangwu@example.com | 正常 | 2100 | |
| 赵六 | zhaoliu@example.com | 已禁用 | 0 |
💡 尝试选中行、添加/删除数据,观察批量操作栏、错误高亮和空状态的自动切换
/* 表格包含选中行时显示批量操作 */
.data-table-container:has(tr.selected) .bulk-actions {
display: flex;
}
/* 表格行包含错误数据时高亮 */
.data-table tbody tr:has(.error-cell) {
background: var(--error-light);
border-left: 4px solid var(--error);
}
/* 表格为空时显示提示 */
.data-table-container:not(:has(tbody tr)) .empty-table-message {
display: block;
}
.data-table-container:not(:has(tbody tr)) .data-table {
display: none;
}
/* 优势:
1. 无需 JavaScript 管理 UI 状态
2. 自动响应数据变化
3. 代码简洁易维护 */
案例 2: 动态表单验证
组合 :has()、:not() 和 :is() 实现复杂的表单验证逻辑,
必填项未填写时自动禁用提交按钮,并提供实时验证反馈。
💡 尝试填写表单,注意提交按钮在必填项未填写时自动禁用,输入无效数据时显示警告
/* 表单包含未填写的必填项时禁用提交按钮 */
.complex-form:has(input[required]:placeholder-shown) .submit-button,
.complex-form:has(select[required][value=""]) .submit-button {
opacity: 0.5;
pointer-events: none;
cursor: not-allowed;
}
/* 表单包含无效输入时显示警告 */
.complex-form:has(:is(input, textarea):invalid:not(:placeholder-shown)) .form-warning {
display: flex;
}
/* 表单全部有效时显示成功提示 */
.complex-form:has(input[required]:not(:placeholder-shown):valid)
:has(select[required]:not([value=""]))
:not(:has(input:invalid))
:not(:has(textarea:invalid)) .form-success {
display: flex;
}
/* 优势:
1. 复杂验证逻辑完全由 CSS 实现
2. 自动响应用户输入
3. 无需编写验证 JavaScript */
案例 3: 条件样式布局
使用 :has() 和 :not() 根据内容的存在与否自动调整布局, 实现智能的响应式设计,无需
JavaScript 或媒体查询。
主内容区
这个布局会根据侧边栏的存在与否自动调整主内容区的宽度。 同时,下方的内容网格会根据项目数量自动调整列数。
数据分析
查看统计数据
趋势报告
分析增长趋势
项目管理
管理项目进度
💡 尝试切换侧边栏和添加/移除内容项,观察布局如何自动调整
/* 根据是否有侧边栏调整主内容宽度 */
.page-container:has(.page-sidebar) .page-main {
width: calc(100% - 270px);
}
.page-container:not(:has(.page-sidebar)) .page-main {
width: 100%;
max-width: 100%;
}
/* 根据内容数量调整网格列数 */
/* 只有 1-2 个项目时单列 */
.content-grid:has(.content-item:nth-child(1))
:not(:has(.content-item:nth-child(3))) {
grid-template-columns: 1fr;
}
/* 有 3-4 个项目时两列 */
.content-grid:has(.content-item:nth-child(3))
:not(:has(.content-item:nth-child(5))) {
grid-template-columns: repeat(2, 1fr);
}
/* 有 5 个或更多项目时三列 */
.content-grid:has(.content-item:nth-child(5)) {
grid-template-columns: repeat(3, 1fr);
}
/* 优势:
1. 布局自动响应内容变化
2. 无需 JavaScript 或媒体查询
3. 代码简洁直观 */
案例 4: 智能导航
组合 :has()、:is() 和 :not() 实现智能的多级导航系统,
自动显示子菜单箭头、高亮当前页面、管理展开/收起状态。
💡 点击按钮切换当前页面,观察导航如何自动高亮父级菜单并展开相关子菜单
/* 当前页面的导航项高亮 */
.smart-navigation a.active {
background: var(--primary);
color: white;
}
/* 包含当前页面链接的父级导航项高亮 */
.smart-navigation li:has(a.active) > a:first-child:not(.active) {
background: var(--primary-light);
color: var(--primary-dark);
border-left: 4px solid var(--primary);
}
/* 导航项包含子菜单时显示箭头 */
.smart-navigation li:has(ul) > a::after {
content: '▼';
position: absolute;
right: 16px;
transition: transform 0.3s;
}
/* 展开包含激活链接的子菜单 */
.smart-navigation li:has(a.active) > ul {
max-height: 500px;
}
/* 旋转箭头 */
.smart-navigation li:has(a.active) > a::after {
transform: rotate(180deg);
}
/* 包含激活子项的多级导航高亮 */
.smart-navigation li:has(li:has(a.active)) > a:first-child:not(.active) {
background: var(--info-light);
color: var(--info-dark);
border-left: 4px solid var(--info);
}
/* 优势:
1. 多级导航自动管理状态
2. 父级菜单自动感知子链接
3. 无需手动添加类名
4. 支持任意深度的嵌套 */
组合选择器的最佳实践
通过这 4 个案例,我们看到了现代选择器组合使用的强大能力。以下是一些最佳实践建议:
✅ 推荐做法
- 优先使用 CSS 实现状态管理
- 组合选择器解决复杂需求
- 保持选择器简洁易读
- 添加注释说明复杂逻辑
- 考虑浏览器兼容性
- 提供降级方案
❌ 避免做法
- 过度嵌套选择器
- 过于复杂的组合逻辑
- 忽略性能影响
- 不考虑可维护性
- 完全依赖现代选择器
- 忽略无障碍访问
🎯 性能考虑
虽然现代选择器非常强大,但在使用时也要注意性能:
:has()选择器可能影响性能,避免在大型列表中过度使用- 尽量将
:has()应用在较小的作用域内 - 避免过深的嵌套和过于复杂的组合
- 使用浏览器开发工具监控性能
- 在必要时考虑使用 JavaScript 替代
⚡ 实战技巧
- 渐进增强 - 先实现基础功能,再用现代选择器增强
- 特性检测 - 使用
@supports检测浏览器支持 - 降级方案 - 为不支持的浏览器提供替代方案
- 测试验证 - 在多个浏览器中测试效果
- 文档记录 - 为复杂选择器添加详细注释
浏览器兼容性
本页面使用的现代选择器在主流浏览器中的支持情况:
| 选择器 | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
:has() |
✓ 105+ | ✓ 121+ | ✓ 15.4+ | ✓ 105+ |
:is() |
✓ 88+ | ✓ 78+ | ✓ 14+ | ✓ 88+ |
:where() |
✓ 88+ | ✓ 78+ | ✓ 14+ | ✓ 88+ |
:not() (复杂) |
✓ 88+ | ✓ 84+ | ✓ 9+ | ✓ 88+ |
如果需要支持旧版浏览器,建议:
- 使用
@supports进行特性检测 - 提供 JavaScript 降级方案
- 使用 PostCSS 等工具进行转换
- 考虑使用 polyfill(性能可能受影响)
更多兼容性信息请访问 Can I Use