0%

高级CSS选择器技巧

CSS 选择器是构建样式的基础,了解高级技巧可以大幅提高可维护性和灵活性。本篇将覆盖一些鲜为人知但非常有用的选择器模式。

属性选择器的灵活应用

除了基本的 [attr=value],还有多种匹配方式:

  • [attr^=value]:以 value 开头。
  • [attr$=value]:以 value 结尾。
  • [attr*=value]:包含 value。
  • [attr|=value]:以 value 或 value- 开头,常用于语言匹配。
  • [attr~=value]:空格分隔的词语之一匹配。

例如,样式所有以 data-role= 开头的元素:

1
2
3
[data-role^="button"] {
cursor: pointer;
}

在表单中,可以通过 [type="submit"] 精确匹配。

伪类与结构匹配

常见伪类如 :first-child:last-of-type 已为人熟知,但还有更多隐藏的宝石:

  • :nth-last-child(an+b):从后面计数。
  • :nth-of-type():not() 组合强大。
  • :only-of-type / :only-child

可用于实现斑马表格效果而无需 JS:

1
tr:nth-of-type(odd) { background: #fafafa; }

更高级的示例:选中所有第 3n+1 个元素,但排除最后一个:

1
2
3
li:nth-of-type(3n+1):not(:last-of-type) {
border-bottom: 1px solid #ccc;
}

:is():where()

这两个伪类可以减少重复书写,并且具有不同的特异性。

  • :is(a, b, c) 相当于 a, b, c,但特异性取最高。
  • :where() 的特异性为零,适合定义通用样式。
1
2
3
4
5
6
7
:is(h1, h2, h3) {
margin: 0;
}

:where(section, article) {
padding: 1rem;
}

当组合时,:where() 可以用来重置父级选择器。

:has() 选择器(实验性)

:has() 可以匹配具有特定子元素的父元素。例如:

1
2
3
div:has(> img) {
padding-top: 50px;
}

支持批注、卡片时特别有用。注意这是一个“父选择器”,目前仍处于实验阶段,仅在部分浏览器可用。

:focus-within:focus-visible

  • :focus-within 为父元素提供焦点状态,例如表单容器。
  • :focus-visible 仅在键盘导航时显示焦点,避免鼠标点击时的虚线框。

例子:

1
2
3
4
5
6
7
.form-group:focus-within {
outline: 2px solid blue;
}

button:focus-visible {
box-shadow: 0 0 0 3px rgba(0,0,255,0.5);
}

文本选择与大小写

  • ::first-letter::first-line 用于文本片段。
  • ::selection 设置文本被选中时的背景/颜色。
  • text-transform: capitalize 结合 ::first-letter 可实现首字母大写。

响应式选择器

新的 @media 媒体查询可以与容器查询、方位查询结合:

1
2
3
@container (min-width: 400px) {
article { font-size: 1.2rem; }
}

此外,:lang() 在多语言页面中很有用。

动态匹配

  • 使用 :nth-child() 来产生动画延迟:
1
2
3
4
li {
animation: fadeIn 0.5s ease forwards;
}
li:nth-child(3n) { animation-delay: 0.3s; }
  • 利用 :is() 写出更简洁的关键帧规则。

伪元素与组合

伪元素 ::before::after 可以与选择器组合,构建复杂装饰:

1
2
3
4
5
6
7
8
9
10
11
12
.button::after {
content: "";
display: block;
width: 100%;
height: 2px;
background: currentColor;
transition: transform 0.3s;
}

.button:hover::after {
transform: scaleX(0);
}

满足无 JS 交互

通过 :checked 和兄弟选择器,可实现纯 CSS 的切换组件:

1
2
3
4
5
6
7
<input type="checkbox" id="toggle" hidden>
<label for="toggle">菜单</label>
<nav>
<ul>
<li>选项</li>
</ul>
</nav>
1
#toggle:checked + label + nav { display: block; }

性能提示

复杂选择器可能影响渲染性能,浏览器从右向左匹配,尽量使用 ID 或类选择器作为锚点。

常见误区

  • 使用 * 通配符会严重降低性能。
  • 过度嵌套选择器导致 specificity 混乱。

兼容性和回退

  • 使用 @supports 检测 :has()
1
2
3
@supports selector(:has(*)) {
/* 支持 */
}
  • 对于不支持容器查询的浏览器,使用 @media 作为回退。

示例项目

创建一个响应式卡片列表:

1
2
3
4
5
6
7
.card-list > :is(.card, .promo) {
margin: 1rem;
}

.card:where(:not(:first-child)) {
border-top: none;
}

工具与调试

  • Chrome DevTools 的「Elements」面板可显示匹配的选择器。
  • document.querySelectorAll('selector') 可在控制台测试。

总结

高级选择器让 CSS 更强大、语义更明确。掌握属性选择器、伪类、和实验性特性能提升项目质量。但要权衡可维护性与性能,避免滥用。随着规范发展,前端工具链也在不断适配,更好地服务于现代 Web 开发。