CSS 教程 / 基本 CSS 选择器:类型、类、ID 与属性

CSS 选择器用于识别规则适用的 HTML 元素。类型选择器匹配标签名,类选择器匹配可复用的类名,ID 选择器匹配标识符,属性选择器匹配属性或其值。

将选择器与相同的 HTML 对比

让我们根据以下四个项目来阅读选择器:A 和 B 是 p,并且具有 notice 类,B 还有 urgent 类。C 是没有类的 p,D 是具有 notice 类的 div。英文字母 A~D 只是用于区分描述中的对象的标记,并不是 CSS 语法。

<p id="opening" class="notice" data-tags="garden visit">A: Operating hours</p>
<p class="notice urgent">B: Rainy weather notice</p>
<p>C: What you need</p>
<div class="notice">D: Information box</div>
选择器 选择什么 判断标准
p A, B, C 标签名是 p
.notice A, B, D 包含 notice 类
p.notice A, B p 且包含 notice 类
.notice.urgent B 同时包含 notice 和 urgent 两个类
#opening A ID 为 opening
[data-tags~="visit"] A 在由空格分隔的属性值中包含单词 visit

在读取选择器时,确保条件作用于应用 CSS 的元素本身。p.notice 中的两个条件指向同一个元素。另一方面,p .notice 中的空格表示匹配 p 的后代中带有 notice 类的元素。根据空格改变目标的规则可以在 CSS 组合器和伪类 的结构中找到。

使用类型和通配选择器

p { color: #333; }
* { box-sizing: border-box; }

p 选择所有 p 元素。通常装饰相同的标签很简单,但要分别设置提示信息和正文段落的样式,则需要额外的条件,例如 class。通配选择器 * 是一种选择所有元素的表示法。它不会自动包括伪元素。

这里,box-sizing: border-box 是一个辅助设置,在指定宽度和高度时计算包括内边距和边框。即便你还没有完全掌握尺寸计算,也可以进行这个练习。使用通配选择器并不意味着必须一次性更改所有文本颜色和背景。考虑通用设置和特定元素的设计。

选择类和 ID

.notice { background-color: #e9f7ef; }
p.notice { border-left: 4px solid #087f5b; }
.notice.urgent { font-weight: bold; }
#opening { color: #087f5b; }

一个类可以在多个元素中重用。class="notice urgent" 在 HTML 中是由两个类名组成的列表,中间用空格分隔,而不是单个名称 notice urgent。在 CSS 中,在前面加一个点来选择 .notice 或 .urgent。.notice.urgent 仅适用于同时具有这两个名称的元素。

在一个 HTML 文档中,ID 必须是唯一的。不要给十个提示元素相同的 id="opening"。类用于可重用的样式,而 ID 用于唯一标识或片段目标。ID 选择器的优先级(specificity)高于类选择器,但这个比较须在适用的来源、重要性和层叠层条件内进行;不加区分地添加 ID 会使冲突更难维护。有关更多详细信息,请参见 CSS 继承、选择器优先级与层叠。

在示例中,我们按 ID 上色以显示不同主体之间的差异。如果你实际上需要对多个提示信息使用相同的绿色,可以通过将颜色添加到 .notice 规则中来简化。应根据实际需要的匹配范围选择合适的选择器。

匹配属性及其值

input[required] { border: 2px solid #087f5b; }
input[type="email"] { background-color: #fff4cc; }
[data-tags~="visit"] { outline: 1px dashed #777; }
a[href^="https://"] { color: #1d4ed8; }
符号 含义 将其应用于示例
[required] 具有 required 属性的元素 区分必填输入字段。即使值为空字符串,如果该属性存在,也会匹配。
[type="email"] 类型值正好是 email 选择电子邮件输入字段。
[data-tags~="visit"] 在以空格分隔的值中包含单词 visit 它匹配 garden visit,但不匹配 revisit。
[href^="https://"] href 字符串以 https:// 开头 选择具有该字符串的链接。它本身不是外部网站识别功能。

https:// 地址可以指向同一个网站,因此该前缀本身并不能识别外部链接。同样,[data-tags="visit"] 匹配整个属性值,而不匹配 garden visit。请为所需条件使用适当的比较运算符。请参阅 MDN:属性选择器 。

运行完整的选择器示例

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Small Garden</title>
  <style>
* { box-sizing: border-box; }
    body { margin: 24px; font-family: sans-serif; line-height: 1.7; }
    p { color: #333; }
    .notice { background-color: #e9f7ef; padding: 12px; }
    p.notice { border-left: 4px solid #087f5b; }
    .notice.urgent { font-weight: bold; }
    #opening { color: #087f5b; }
    [data-tags~="visit"] { outline: 1px dashed #777; }
    a[href^="https://"] { color: #1d4ed8; }
    input[required] { border: 2px solid #087f5b; }
    input[type="email"] { background-color: #fff4cc; }
  </style>
</head>
<body>
<h1>Small Garden</h1>
  <p id="opening" class="notice" data-tags="garden visit">A: We open at 9am every day.</p>
  <p class="notice urgent">B: In case of rain, the outdoor program will be canceled.</p>
  <p>C: Bring a water bottle and comfortable shoes.</p>
  <div class="notice">D: This is an information box.</div>
  <p><a href="https://example.com/">E: External guidance link</a></p>
  <form>
    <label for="email">Email (required)</label>
    <input id="email" type="email" name="email" required>
    <button type="submit">Request information</button>
  </form>
</body>
</html>

如果你使用 index.html 保存并打开,A·B·D 将有浅色背景和 12px 内边距,只有 A·B 对应 p.notice 会有左边框。B 有两个类,看起来是加粗的。A 的 ID 为 opening,因此文字为绿色,同时由于 visit 属性值也创建了虚线轮廓。C 仍然是普通段落。

电子邮件输入框在必填条件下边框变粗,在类型条件下背景变为黄色。必填的实际输入验证功能由 HTML 属性处理,而 CSS 仅改变输入框的外观。示例中的外部链接地址仅供说明,请不要将其作为实际服务的指南链接。选择属性存在的方法与选择验证结果的方法不同。CSS 表单状态:焦点、验证、disabled 与 readonly 对比必填和错误状态选择器。

更改条件并预测结果

  1. 尝试将 p.notice 改为 .notice 以扩大左边框的目标。预期结果是原本只存在于 A·B 的边框也会出现在 D 中。确认后,恢复原来的选择器。
  2. 将 B 的类改为 class="urgent"。B 仍然是 p,但它失去了 notice 条件,因此原有的提示背景、左边框以及由 .notice.urgent 设置的粗体文字都会消失。复杂选择器不会仅因为 urgent 类而匹配。
  3. 将 A 的 data-tags 值改为 garden revisit。由于没有独立的 visit 单词,虚线轮廓应消失。确保不要将 visit 和 revisit 当作子字符串混淆。

对于每个练习,保存文件然后刷新以检查并返回到原始值。如果只有预期对象没有变化,首先比较实际的 class、id 和属性名称。您可以通过查看开发者工具来判断选择错误和优先级冲突,看规则是否与选定的元素匹配。