属性选择器

学习

属性选择器

2026-02-23/0/ 编辑


属性选择器

概述

属性选择器(Attribute Selectors)用于选择具有特定属性的元素,或者属性值满足特定条件的元素。

语法

[属性名] {
  /* 选择具有该属性的元素 */
}

[属性名="值"] {
  /* 选择属性值完全匹配的元素 */
}

[属性名~="值"] {
  /* 选择属性值包含该词的元素(词列表) */
}

[属性名|="值"] {
  /* 选择属性值以该值开头的元素(或该值后连字符) */
}

[属性名^="值"] {
  /* 选择属性值以该字符串开头的元素 */
}

[属性名$="值"] {
  /* 选择属性值以该字符串结尾的元素 */
}

[属性名*="值"] {
  /* 选择属性值包含该字符串的元素 */
}

基本用法

1. 存在属性选择器

选择具有指定属性的元素,不考虑属性值。

/* 选择具有 title 属性的元素 */
[title] {
  border: 1px solid red;
}

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

/* 选择具有 required 属性的表单元素 */
input[required] {
  border-color: #e74c3c;
}
<div title="提示信息">有 title</div>
<div>无 title</div>
<input type="text" disabled>
<input type="text" required>

2. 精确匹配

选择属性值完全等于指定值的元素。

/* 选择 type 为 text 的输入框 */
input[type="text"] {
  width: 100%;
  padding: 10px;
}

/* 选择 href 精确匹配的链接 */
a[href="https://example.com"] {
  color: red;
}

/* 选择 target 为 _blank 的链接 */
a[target="_blank"]::after {
  content: " ↗";
}

3. 部分匹配

[属性名~="值"] - 词列表匹配

选择属性值包含指定词的元素(词之间用空格分隔)。

/* 选择 class 包含 "box" 的元素 */
[class~="box"] {
  border: 1px solid #3498db;
}
<div class="box">匹配</div>
<div class="box active">匹配</div>
<div class="box-red">不匹配</div>
<div class="box2">不匹配</div>

[属性名|="值"] - 连字符分隔的前缀匹配

选择属性值以指定值开头,或以该值加连字符开头的元素。

/* 选择 lang 以 "en" 开头的元素 */
[lang|="en"] {
  font-family: Arial, sans-serif;
}
<p lang="en">匹配</p>
<p lang="en-US">匹配</p>
<p lang="en-GB">匹配</p>
<p lang="zh">不匹配</p>

[属性名^="值"] - 开头匹配

选择属性值以指定字符串开头的元素。

/* 选择 class 以 "icon-" 开头的元素 */
[class^="icon-"] {
  display: inline-block;
  width: 20px;
  height: 20px;
  background-repeat: no-repeat;
}

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

/* 选择 src 以 "http://" 开头的图片 */
img[src^="http://"] {
  display: none; /* 不显示非 HTTPS 图片 */
}
<i class="icon-user"></i>
<i class="icon-home"></i>
<i class="icon-home-active"></i>
<i class="my-icon"></i> <!-- 不匹配 -->

[属性名$="值"] - 结尾匹配

选择属性值以指定字符串结尾的元素。

/* 选择 href 以 ".pdf" 结尾的链接 */
a[href$=".pdf"]::after {
  content: " (PDF)";
  color: #e74c3c;
}

/* 选择 src 以 ".jpg" 结尾的图片 */
img[src$=".jpg"] {
  border: 2px solid #3498db;
}

/* 选择 class 以 "-active" 结尾的元素 */
[class$="-active"] {
  color: #3498db;
  font-weight: bold;
}
<a href="document.pdf">下载文档</a>
<a href="page.html">普通链接</a>
<div class="box-active">激活状态</div>
<div class="active-box">不匹配</div>

[属性名*="值"] - 包含匹配

选择属性值包含指定字符串的元素。

/* 选择 href 包含 "example" 的链接 */
a[href*="example"] {
  color: #3498db;
}

/* 选择 src 包含 "logo" 的图片 */
img[src*="logo"] {
  border: 2px solid gold;
}

/* 选择 class 包含 "box" 的元素 */
[class*="box"] {
  padding: 10px;
}
<a href="https://example.com">匹配</a>
<a href="https://test.com">不匹配</a>
<img src="logo.png">
<img src="header.png">

权重计算

属性选择器的权重为 10:

[type="text"] {
  /* 权重 = 10 */
}

input[type="text"] {
  /* 权重 = 1 + 10 = 11 */
}

.box[class~="active"] {
  /* 权重 = 10 + 10 = 20 */
}

常见应用场景

1. 表单样式

/* 文本输入框 */
input[type="text"],
input[type="email"],
input[type="password"],
textarea {
  width: 100%;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

/* 单选框和复选框 */
input[type="radio"],
input[type="checkbox"] {
  width: 16px;
  height: 16px;
  cursor: pointer;
}

/* 按钮 */
input[type="submit"],
input[type="button"],
button {
  padding: 10px 20px;
  background: #3498db;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

2. 链接样式

/* 外部链接 */
a[href^="http"]::after {
  content: " ↗";
  font-size: 0.8em;
}

/* 邮箱链接 */
a[href^="mailto:"]::before {
  content: "✉ ";
}

/* 电话链接 */
a[href^="tel:"]::before {
  content: "📞 ";
}

/* PDF 链接 */
a[href$=".pdf"]::after {
  content: " (PDF)";
  color: #e74c3c;
  font-size: 0.8em;
}

/* 压缩文件链接 */
a[href$=".zip"],
a[href$=".rar"]::after {
  content: " (下载)";
  color: #f39c12;
  font-size: 0.8em;
}

3. 图标样式

/* 所有图标 */
[class^="icon-"],
[class*=" icon-"] {
  display: inline-block;
  width: 16px;
  height: 16px;
  background-image: url(icons.png);
  background-repeat: no-repeat;
}

/* 特定图标 */
.icon-home {
  background-position: 0 0;
}

.icon-user {
  background-position: -16px 0;
}

.icon-settings {
  background-position: -32px 0;
}

4. 社交媒体链接

/* Twitter 链接 */
a[href*="twitter.com"] {
  color: #1da1f2;
}

/* Facebook 链接 */
a[href*="facebook.com"] {
  color: #1877f2;
}

/* LinkedIn 链接 */
a[href*="linkedin.com"] {
  color: #0077b5;
}

/* GitHub 链接 */
a[href*="github.com"] {
  color: #333;
}

5. 图片样式

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

/* PNG 图片 */
img[src$=".png"] {
  background: white;
  padding: 10px;
}

/* JPG 图片 */
img[src$=".jpg"],
img[src$=".jpeg"] {
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

6. 数据属性

/* 基于 data 属性的样式 */
[data-color="red"] {
  background-color: #e74c3c;
  color: white;
}

[data-color="blue"] {
  background-color: #3498db;
  color: white;
}

[data-color="green"] {
  background-color: #27ae60;
  color: white;
}

/* 悬停提示 */
[data-tooltip]:hover::after {
  content: attr(data-tooltip);
  position: absolute;
  background: #333;
  color: white;
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
}
<div data-color="red">红色背景</div>
<div data-color="blue">蓝色背景</div>
<span data-tooltip="这是提示信息">悬停查看</span>

7. 必填和禁用状态

/* 必填字段 */
input[required],
textarea[required],
select[required] {
  border-left: 3px solid #e74c3c;
}

input[required]::after,
textarea[required]::after {
  content: " *";
  color: #e74c3c;
}

/* 禁用字段 */
input[disabled],
textarea[disabled],
select[disabled] {
  background-color: #f5f5f5;
  color: #999;
  cursor: not-allowed;
  opacity: 0.7;
}

8. 自定义属性

/* 基于 data 属性的组件样式 */
.card[data-size="small"] {
  padding: 10px;
  font-size: 14px;
}

.card[data-size="medium"] {
  padding: 15px;
  font-size: 16px;
}

.card[data-size="large"] {
  padding: 20px;
  font-size: 18px;
}

/* 主题颜色 */
.button[data-theme="primary"] {
  background: #3498db;
}

.button[data-theme="success"] {
  background: #27ae60;
}

.button[data-theme="danger"] {
  background: #e74c3c;
}

.button[data-theme="warning"] {
  background: #f39c12;
}
<div class="card" data-size="small">小卡片</div>
<div class="card" data-size="medium">中卡片</div>
<div class="card" data-size="large">大卡片</div>

<button class="button" data-theme="primary">主要按钮</button>
<button class="button" data-theme="success">成功按钮</button>

9. 多条件组合

/* 同时满足多个条件 */
input[type="text"][placeholder*="用户"] {
  background-color: #f0f8ff;
}

a[href^="http"][href*="example"] {
  color: #e74c3c;
  font-weight: bold;
}

/* 组合选择器 */
.box[data-size="large"].active {
  transform: scale(1.1);
  box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}

10. 图片优化

/* 懒加载图片 */
img[loading="lazy"] {
  opacity: 0;
  transition: opacity 0.3s ease;
}

img[loading="lazy"].loaded {
  opacity: 1;
}

/* 响应式图片 */
img[srcset] {
  width: 100%;
  height: auto;
}

/* 视频封面 */
video[poster] {
  width: 100%;
  height: auto;
}

实战案例

案例1: 文件下载列表

.download-list a {
  display: block;
  padding: 10px 15px;
  background: #f9f9f9;
  border-radius: 4px;
  margin-bottom: 5px;
}

.download-list a[href$=".pdf"] {
  border-left: 4px solid #e74c3c;
}

.download-list a[href$=".pdf"]::before {
  content: "📄";
  margin-right: 10px;
}

.download-list a[href$=".zip"],
.download-list a[href$=".rar"] {
  border-left: 4px solid #f39c12;
}

.download-list a[href$=".zip"]::before,
.download-list a[href$=".rar"]::before {
  content: "📦";
  margin-right: 10px;
}
<div class="download-list">
  <a href="document.pdf">产品手册</a>
  <a href="files.zip">资源包</a>
  <a href="data.rar">数据文件</a>
</div>

案例2: 表单验证样式

.form-group {
  margin-bottom: 20px;
}

/* 必填字段 */
.form-group input:required,
.form-group textarea:required {
  border-left: 3px solid #e74c3c;
}

.form-group input:required::placeholder,
.form-group textarea:required::placeholder {
  color: #e74c3c;
}

/* 验证通过 */
.form-group input:valid,
.form-group textarea:valid {
  border-color: #27ae60;
}

/* 验证失败 */
.form-group input:invalid:not(:placeholder-shown),
.form-group textarea:invalid:not(:placeholder-shown) {
  border-color: #e74c3c;
}

.form-group input:invalid:not(:placeholder-shown) + .error-msg,
.form-group textarea:invalid:not(:placeholder-shown) + .error-msg {
  display: block;
}

.error-msg {
  display: none;
  color: #e74c3c;
  font-size: 12px;
  margin-top: 5px;
}

案例3: 社交媒体图标

.social-links a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  color: white;
  text-decoration: none;
  transition: transform 0.3s ease;
}

.social-links a[href*="twitter.com"] {
  background: #1da1f2;
}

.social-links a[href*="facebook.com"] {
  background: #1877f2;
}

.social-links a[href*="linkedin.com"] {
  background: #0077b5;
}

.social-links a[href*="github.com"] {
  background: #333;
}

.social-links a:hover {
  transform: scale(1.1);
}
<div class="social-links">
  <a href="https://twitter.com" title="Twitter">T</a>
  <a href="https://facebook.com" title="Facebook">F</a>
  <a href="https://linkedin.com" title="LinkedIn">L</a>
  <a href="https://github.com" title="GitHub">G</a>
</div>

案例4: 响应式图片

/* 懒加载 */
img[loading="lazy"] {
  opacity: 0;
  transition: opacity 0.5s ease;
}

img[loading="lazy"].loaded {
  opacity: 1;
}

/* 响应式图片 */
picture img {
  width: 100%;
  height: auto;
}

/* 不同格式支持 */
picture source[type="image/avif"] {
  /* AVIF 格式 */
}

picture source[type="image/webp"] {
  /* WebP 格式 */
}

案例5: 主题切换

/* 主题容器 */
[data-theme="light"] {
  --bg-color: #ffffff;
  --text-color: #333333;
}

[data-theme="dark"] {
  --bg-color: #1a1a1a;
  --text-color: #ffffff;
}

/* 应用主题变量 */
body {
  background-color: var(--bg-color);
  color: var(--text-color);
  transition: background-color 0.3s ease, color 0.3s ease;
}

/* 主题特定样式 */
[data-theme="light"] .card {
  background: white;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

[data-theme="dark"] .card {
  background: #2a2a2a;
  box-shadow: 0 2px 10px rgba(0,0,0,0.3);
}
<div data-theme="light">
  <div class="card">内容</div>
</div>

<div data-theme="dark">
  <div class="card">内容</div>
</div>

注意事项

  1. 属性区分大小写: HTML 属性名不区分大小写,但属性值可能区分
  2. 引号使用: 属性值可以用单引号、双引号或不加引号
  3. 性能考虑: 复杂的属性选择器可能影响性能
  4. 浏览器兼容: 大部分属性选择器在现代浏览器中都支持
  5. data 属性: 自定义 data 属性是很好的做法

最佳实践

  1. 语义化: 使用 data-* 属性传递语义信息
  2. 渐进增强: 为不支持的浏览器提供回退
  3. 性能优化: 避免过于复杂的属性选择器
  4. 代码可读: 添加注释说明复杂选择器
  5. 组合使用: 与其他选择器配合使用
  6. 规范命名: data-* 属性命名要规范
  7. 测试兼容: 测试浏览器兼容性
  8. 避免过度: 不要过度依赖属性选择器

总结

属性选择器是 CSS 中非常强大的选择器,能够基于元素的属性进行精确选择。掌握各种属性选择器的使用方法,可以帮助我们创建更灵活、更可维护的样式代码。在实际开发中,要合理使用属性选择器,确保代码的可读性和性能。