类选择器
类选择器是一个点后面跟上类名。只要元素的 class 属性中包含这个类名,无论是什么元素,都会应用这条样式。
点只出现在 CSS 中。在 HTML 中,属性写作 class="badge",不带点。类名区分大小写:.Badge 不会匹配 class="badge"。
一个元素上的多个类
一个元素可以带任意多个类,用空格分隔。每个类带来各自的规则,用小块组合出不同的变体就是这样做的:
不带空格的 .btn.danger 匹配同时带有这两个类的元素。最后一个 span 有 danger 但没有 btn,所以链式规则会跳过它。
类选择器的各种写法
| 选择器 | 匹配 |
|---|---|
.note | 任何带 note 类的元素 |
p.note | 只匹配带 note 类的 <p> 元素 |
.btn.primary | 同时带有 btn 和 primary 的元素 |
.card .title | .card 内部任意位置的 .title |
.card > .title | 父元素是 .card 的 .title |
.a, .b | 带 a 或 b 的元素 |
有空格和没有空格的区别,以及更多组合器,见 CSS 选择器页面。
ID 选择器
ID 选择器是一个井号后面跟上 id:#site-header 为带 id="site-header" 的元素设置样式。id 在页面中必须唯一,所以 ID 选择器只会选中一个元素。
id 的用途不只是样式:href="#details" 会滚动到这个元素,<label for="email"> 指向输入框的 id,JavaScript 用 document.getElementById('details') 找到它。这些才是给元素加 id 的常见理由;至于样式,类是更好的工具。
class 与 id 的区别
类 .name | ID #name | |
|---|---|---|
| 每个页面 | 多个元素 | 一个元素 |
| 每个元素 | 多个,用空格分隔 | 一个 |
| 优先级 | (0,1,0) | (1,0,0) |
链接目标(URL 中的 #name) | 不能 | 能 |
| 最适合 | 设置样式 | 锚点、label、JavaScript 钩子 |
优先级上的差距,正是实际开发中用类来写样式的原因。一个 ID 胜过任意多个类,所以用 ID 写的规则只能被另一个 ID、行内样式或 !important 覆盖:
用 JavaScript 添加和移除类
用类来改变元素的外观是 JavaScript 的常规做法:CSS 定义各种状态,脚本只负责切换。
classList 还有 add、remove、contains 和 replace。避免直接给 className 赋值:它会替换掉元素原有的所有类。
类的命名
- 字母、数字、连字符和下划线都可以放心使用:
card、card-title、card__title、is-open。 - 选择器不要以数字开头,也不要以连字符加数字开头。
.2col是无效的 CSS。用字母开头(.cols-2),或者转义这个数字(.\32 col)。 - 按用途命名,而不是按外观命名:
.error在改版后依然适用,.red-text就不行了。 - 在较大的项目中,命名规范很有帮助。BEM 的写法是
block__element--modifier,例如.card__title--large。
常见错误
- 在 HTML 中写了点。
class=".badge"永远不会匹配.badge。 - 写了两个
class属性。<p class="a" class="b">只保留a。请写成class="a b"。 - 想选同时带两个类的元素,却加了空格。
.btn .primary查找的是嵌套的元素;.btn.primary才是同一个元素。 - 重复使用 id。 重复的 id 会破坏
getElementById、锚点链接和 label 的关联,即使 CSS 看起来正常。 - 所有样式都用 id 写。 它的优先级会让之后的覆盖变得很麻烦;请用类。
常见问题
CSS 中如何选择一个类?
写一个点,后面跟上类名:.card { ... } 会为所有带 class="card" 的元素设置样式。点只出现在 CSS 中,HTML 属性里没有点。
CSS 中 class 和 id 有什么区别?
一个类可以用在任意多个元素上,一个元素也可以有多个类;id 在页面中必须唯一,一个元素最多只有一个 id。在 CSS 中,#id 的优先级比 .class 高得多,所以 ID 规则更难被覆盖。
如何给一个元素添加两个类?
在同一个属性里用空格分隔类名:class="btn primary"。在一个元素上写两次 class 是无效的,浏览器只保留第一个属性。
如何选择同时带有两个类的元素?
把类选择器连在一起写,中间不加空格:.btn.primary 匹配同时带有这两个类的元素。加了空格的 .btn .primary 表示 .btn 元素内部的 .primary 元素。
CSS 类名可以以数字开头吗?
在 HTML 中可以,但选择器不能以未转义的数字开头,所以 .1col 是无效的 CSS。可以转义这个数字(.\31 col),更好的做法是让类名以字母开头。