Skip to content

CSS 高级选择器:精准定位元素的强大工具

选择器的本质

CSS 选择器就像是一个"地址系统",它告诉浏览器:"我想给这些特定的元素应用样式"。基础选择器(类选择器、ID 选择器、元素选择器)就像给一个城市中的所有餐厅涂上颜色,而高级选择器则能让你精确到"位于 Main Street 上、门牌号以 5 开头的餐厅"。

掌握高级选择器,意味着你能用更少的代码、更优雅的方式控制页面样式,而不需要给每个元素都添加类名。

属性选择器

属性选择器允许你根据元素的属性和属性值来选择元素。这在处理表单、链接等场景时特别有用。

基本属性选择器

css
/* 选择所有带有 title 属性的元素 */
[title] {
  border-bottom: 1px dotted #999;
  cursor: help;
}

/* 选择所有带有 disabled 属性的 input */
input[disabled] {
  background-color: #f5f5f5;
  cursor: not-allowed;
}

/* 选择所有带有 required 属性的表单控件 */
[required] {
  border-left: 3px solid #e74c3c;
}

精确匹配属性值

css
/* 选择 type 属性值为 "text" 的 input */
input[type="text"] {
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

/* 选择 target 属性值为 "_blank" 的链接 */
a[target="_blank"] {
  padding-right: 18px;
  background: url("external-link.svg") no-repeat right center;
  background-size: 14px 14px;
}

/* 选择特定语言的内容 */
[lang="en"] {
  font-family: "Georgia", serif;
}

[lang="zh"] {
  font-family: "Microsoft YaHei", sans-serif;
}

模糊匹配属性值

CSS 提供了多种模糊匹配方式,每种都有特定的使用场景:

css
/* ^= 开头匹配:选择 href 以 "https://" 开头的链接 */
a[href^="https://"]
{
  color: #27ae60;
}

a[href^="http://"]
{
  color: #f39c12;
}

/* $= 结尾匹配:根据文件扩展名设置不同图标 */
a[href$=".pdf"] {
  padding-left: 20px;
  background: url("pdf-icon.svg") no-repeat left center;
}

a[href$=".zip"] {
  padding-left: 20px;
  background: url("zip-icon.svg") no-repeat left center;
}

a[href$=".doc"],
a[href$=".docx"] {
  padding-left: 20px;
  background: url("doc-icon.svg") no-repeat left center;
}

/* *= 包含匹配:选择 class 包含 "button" 的元素 */
[class*="button"] {
  cursor: pointer;
  user-select: none;
}

/* ~= 词列表匹配:选择 class 属性中包含完整单词 "highlight" 的元素 */
[class~="highlight"] {
  background-color: yellow;
}

/* |= 前缀匹配:主要用于语言代码,如 lang="en" 或 lang="en-US" */
[lang|="en"] {
  quotes: '"' '"' "'" "'";
}

实际应用案例

css
/* 邮箱输入框自动识别 */
input[type="email"] {
  background-image: url("email-icon.svg");
  background-repeat: no-repeat;
  background-position: 10px center;
  background-size: 16px;
  padding-left: 35px;
}

/* 外部链接自动标识 */
a[href^="http"]:not([href*="mywebsite.com"])::after {
  content: " ↗";
  font-size: 0.8em;
  color: #3498db;
}

/* 下载链接统一样式 */
a[download] {
  display: inline-flex;
  align-items: center;
  padding: 8px 16px;
  background-color: #3498db;
  color: white;
  text-decoration: none;
  border-radius: 4px;
  transition: background-color 0.3s;
}

a[download]:hover {
  background-color: #2980b9;
}

/* 表单验证状态 */
input[aria-invalid="true"] {
  border-color: #e74c3c;
  background-color: #fadbd8;
}

input[aria-invalid="false"] {
  border-color: #27ae60;
  background-color: #d5f4e6;
}

组合选择器

组合选择器定义了元素之间的关系,让你能够基于 DOM 树结构来选择元素。

后代选择器(空格)

后代选择器选择某元素的所有后代元素,无论层级多深:

css
/* 选择 article 内的所有 p 元素 */
article p {
  line-height: 1.8;
  color: #333;
}

/* 选择 nav 内的所有链接 */
nav a {
  text-decoration: none;
  color: #2c3e50;
  transition: color 0.3s;
}

/* 多层嵌套 */
.sidebar .widget ul li a {
  display: block;
  padding: 5px 10px;
}

使用场景:当你想给某个容器内的所有特定元素应用样式,而不关心它们的具体嵌套层级时。

子选择器(>)

子选择器只选择直接子元素,不会影响更深层的后代:

css
/* 只选择 nav 的直接子元素 ul */
nav > ul {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* 只选择 .menu 的直接子 li */
.menu > li {
  position: relative;
  padding: 10px 20px;
}

/* 与后代选择器对比 */
.sidebar ul li {
  /* 选择所有层级的 li */
  margin-left: 20px;
}

.sidebar > ul > li {
  /* 只选择第一层的 li */
  margin-left: 0;
  font-weight: bold;
}

使用场景:当你只想影响直接子元素,避免样式层层传递时。比如多级菜单中只给第一级设置样式。

相邻兄弟选择器(+)

相邻兄弟选择器选择紧跟在某元素后面的第一个兄弟元素:

css
/* 标题后的第一个段落使用引言样式 */
h2 + p {
  font-size: 1.2em;
  font-style: italic;
  color: #555;
  margin-top: 0;
}

/* 复选框选中时,改变其后紧邻的 label 样式 */
input[type="checkbox"]:checked + label {
  color: #27ae60;
  font-weight: bold;
}

/* 错误信息紧跟在输入框后 */
input:invalid + .error-message {
  display: block;
  color: #e74c3c;
  font-size: 0.9em;
  margin-top: 4px;
}

使用场景:自定义表单样式、创建手风琴效果、实现特殊排版需求等。

通用兄弟选择器(~)

通用兄弟选择器选择某元素后面的所有兄弟元素(不一定紧邻):

css
/* 选中的标签页后,所有的标签页样式 */
.tab:checked ~ .tab-content {
  display: block;
}

/* h2 后的所有段落 */
h2 ~ p {
  text-indent: 2em;
}

/* 激活状态影响后续元素 */
.item:hover ~ .item {
  opacity: 0.6;
}

使用场景:当你需要根据某个元素的状态影响其后所有兄弟元素时,比如实现纯 CSS 的标签页切换。

组合选择器实战

css
/* 复杂的导航菜单 */
nav > ul > li {
  position: relative;
}

/* 二级菜单默认隐藏 */
nav > ul > li > ul {
  position: absolute;
  top: 100%;
  left: 0;
  display: none;
  background: white;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* 鼠标悬停时显示 */
nav > ul > li:hover > ul {
  display: block;
}

/* 面包屑导航 */
.breadcrumb li + li::before {
  content: "/";
  padding: 0 8px;
  color: #999;
}

/* 卡片列表布局 */
.card-grid > .card {
  background: white;
  border-radius: 8px;
  padding: 20px;
}

.card-grid > .card + .card {
  margin-top: 20px;
}

/* 表单组 */
.form-group input:focus ~ label {
  color: #3498db;
  transform: translateY(-20px);
  font-size: 12px;
}

通用选择器与组合使用

通用选择器 * 可以选择所有元素,虽然单独使用性能较差,但与其他选择器组合使用时非常强大:

css
/* 重置所有元素的内外边距 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* 选择 .container 下的所有直接子元素 */
.container > * {
  margin-bottom: 20px;
}

.container > *:last-child {
  margin-bottom: 0;
}

/* 选择 article 内的所有元素 */
article * {
  max-width: 100%;
}

/* 清除浮动的经典方法 */
.clearfix::after {
  content: "";
  display: table;
  clear: both;
}

/* 给所有表单元素统一样式 */
form * {
  font-family: inherit;
}

选择器性能考虑

浏览器解析 CSS 选择器是从右向左的,这意味着越具体的选择器性能越好:

css
/* 性能较差:浏览器需要遍历所有 a 标签 */
div div div a {
  color: blue;
}

/* 性能较好:直接定位到 .nav-link */
.nav-link {
  color: blue;
}

/* 避免使用通配符作为主选择器 */
/* 差 */
* .widget {
  margin: 10px;
}

/* 好 */
.widget {
  margin: 10px;
}

最佳实践

  • 尽量使用类选择器,避免过深的嵌套
  • 避免使用通配选择器作为关键选择器(最右边的选择器)
  • ID 选择器性能最好,但降低了可重用性
  • 保持选择器简洁,一般不超过 3-4 层

实战技巧

智能表单样式

css
/* 根据输入类型自动调整 */
input[type="number"],
input[type="tel"] {
  text-align: right;
}

input[type="search"] {
  border-radius: 20px;
  padding-left: 15px;
}

/* 占位符样式 */
input::placeholder {
  color: #999;
  font-style: italic;
}

/* 自动填充样式 */
input:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px white inset;
}

响应式图片处理

css
/* 所有图片响应式 */
img {
  max-width: 100%;
  height: auto;
}

/* 特定比例的图片 */
img[width][height] {
  aspect-ratio: attr(width) / attr(height);
}

/* SVG 图片特殊处理 */
img[src$=".svg"] {
  width: 100%;
  height: auto;
}

打印样式

css
/* 打印时隐藏导航和侧边栏 */
@media print {
  nav,
  aside,
  .no-print {
    display: none;
  }

  /* 链接后显示 URL */
  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.8em;
    color: #666;
  }
}

总结

高级选择器是 CSS 的核心能力之一。通过合理使用属性选择器和组合选择器,你可以编写更加简洁、可维护的样式代码。

核心要点

  • 属性选择器:提供基于 HTML 属性的精确选择能力
    • 基本选择:[attr] 选择具有特定属性的元素
    • 精确匹配:[attr="value"] 选择属性值完全匹配的元素
    • 模糊匹配:^=(开头)、$=(结尾)、*=(包含)提供灵活的匹配方式
  • 组合选择器:基于 DOM 树结构关系选择元素
    • 后代选择器(空格):选择所有后代元素
    • 子选择器(>):只选择直接子元素
    • 相邻兄弟选择器(+):选择紧跟的第一个兄弟
    • 通用兄弟选择器(~):选择后面所有兄弟元素
  • 性能优化:保持选择器简洁,避免过深嵌套,谨慎使用通配选择器
  • 实用场景:表单美化、链接标识、打印样式、响应式图片等