CSS 选择器有哪些?优先级?哪些属性可以继承?
问题解析
CSS 选择器是样式应用的基础,优先级计算是样式冲突时的裁决机制,而属性继承则关系到样式的传播方式。这三个概念是 CSS 最核心的基础知识。
CSS 选择器类型
基础选择器
| 选择器 | 示例 | 说明 |
|---|---|---|
| 元素选择器 | div |
选择所有 div 元素 |
| 类选择器 | .class |
选择 class 包含指定值的元素 |
| ID 选择器 | #id |
选择指定 id 的元素 |
| 通配符 | * |
选择所有元素 |
| 属性选择器 | [type="text"] |
选择有指定属性的元素 |
组合选择器
| 选择器 | 示例 | 说明 |
|---|---|---|
| 后代选择器 | div p |
选择 div 内的所有 p(包括子孙) |
| 子选择器 | div > p |
选择 div 的直接子元素 p |
| 相邻兄弟 | h1 + p |
选择紧邻 h1 的 p |
| 通用兄弟 | h1 ~ p |
选择 h1 之后的所有 p |
| 群组选择器 | h1, h2, p |
同时选择多个元素 |
伪类选择器
/* 状态伪类 */
a:link /* 未访问 */
a:visited /* 已访问 */
a:hover /* 悬停 */
a:active /* 激活 */
input:focus /* 聚焦 */
input:disabled /* 禁用 */
input:checked /* 选中 */
/* 结构伪类 */
li:first-child /* 第一个子元素 */
li:last-child /* 最后一个子元素 */
li:nth-child(2n+1) /* 奇数项 */
li:nth-of-type(2) /* 第2个同类型子元素 */
li:only-child /* 唯一的子元素 */
li:empty /* 空元素 */
/* 其他 */
:not(.exclude) /* 排除指定选择器 */
:target /* 锚点目标元素 */
:root /* 根元素(html) */
伪元素选择器
::before /* 元素内容前插入 */
::after /* 元素内容后插入 */
::first-letter /* 首字母 */
::first-line /* 首行 */
::selection /* 选中的文本 */
::placeholder /* 输入框占位符 */
CSS3 新增选择器
/* 属性选择器扩展 */
[class^="btn-"] /* 以 btn- 开头 */
[class$="-active"] /* 以 -active 结尾 */
[class*="icon"] /* 包含 icon */
/* 结构伪类扩展 */
:first-of-type, :last-of-type
:nth-last-child(), :nth-last-of-type()
:only-of-type
优先级计算
特异性 (Specificity)
优先级由四个部分组成:(a, b, c, d)
| 位置 | 对应选择器 | 权重 |
|---|---|---|
| a | 行内样式 (style="") | 1/0 |
| b | ID 选择器 | 数量 |
| c | 类选择器、属性选择器、伪类 | 数量 |
| d | 元素选择器、伪元素 | 数量 |
计算示例
/* 0,0,0,1 */
p { }
/* 0,0,1,0 */
.container { }
/* 0,1,0,0 */
#header { }
/* 0,1,2,2 */
#header .nav li a:hover { }
/* 1个ID + 2个类(.nav, :hover) + 2个元素(li, a) */
/* 1,0,0,0 - 最高 */
style="color: red"
比较规则
从左到右比较,一旦某位较大,立即停止:
/* 0,0,2,0 > 0,0,1,3 */
.nav .item { } /* 胜 */
.nav li a span { }
!important
.text { color: blue !important; }
注意事项:
!important覆盖任何优先级- 同一元素多个
!important,优先级规则仍适用 - 尽量避免使用,会导致维护困难
继承属性
可继承属性
| 类别 | 属性 |
|---|---|
| 字体 | font-family, font-size, font-weight, font-style, line-height |
| 文本 | color, text-align, text-indent, text-transform, letter-spacing, word-spacing, white-space |
| 可见性 | visibility, cursor |
| 列表 | list-style, list-style-type, list-style-position |
| 表格 | border-collapse, border-spacing, caption-side |
不可继承属性
| 类别 | 属性 |
|---|---|
| 盒模型 | width, height, margin, padding, border |
| 背景 | background, background-color, background-image |
| 定位 | position, top, left, right, bottom, z-index, float, clear |
| 显示 | display, overflow, clip |
| 其他 | vertical-align, text-decoration, content |
继承的例外
某些元素有默认样式,不会继承父元素:
/* a 标签的颜色不会继承父元素 */
a { color: blue; } /* 浏览器默认 */
/* 标题的字体大小 */
h1 { font-size: 2em; }
/* 需要显式继承 */
a { color: inherit; }
深入理解
优先级陷阱
/* 你以为 11 个类能超过 1 个 ID?不! */
.a.b.c.d.e.f.g.h.i.j.k { } /* 0,0,11,0 */
#id { } /* 0,1,0,0 - 胜 */
层叠顺序
当优先级相同时,后定义的样式生效:
.text { color: red; }
.text { color: blue; } /* 生效 */
继承 vs 层叠
<div class="parent" style="color: red;">
<p class="child">文本</p>
</div>
.child { color: blue; }
结果:蓝色(层叠优先于继承)
使用 CSS 变量提高可维护性
:root {
--color-primary: #1890ff;
--color-text: #333;
}
/* 修改变量即可全局生效,无需考虑优先级战争 */
.btn { background: var(--color-primary); }
.text { color: var(--color-text); }
最佳实践
- 避免 ID 选择器:特异性过高,难以覆盖
- 降低嵌套层级:不超过 3 层
- 使用 BEM 命名:
.block { } .block__element { } .block--modifier { } - 谨慎使用 !important:只用于覆盖第三方库样式
- 利用继承减少代码:合理设置父元素的字体、颜色等
/* 不推荐 */
#header .nav ul li a { color: red; }
/* 推荐 */
.nav-link { color: red; }
面试要点
- 能够计算任意选择器的优先级
- 理解为什么 ID 选择器应该少用
- 知道哪些属性可以继承,哪些不能
- 理解 !important 的使用场景和危害
- 了解 BEM 等命名规范对优先级管理的作用