CSS 选择器及优先级详解
CSS 选择器是样式表的核心组成部分,它们决定了样式规则应用到哪些 HTML 元素上。理解选择器的工作原理及其优先级规则,对于编写可维护且高效的 CSS 至关重要。
基本选择器
基本选择器是 CSS 中最基础也是最常用的选择器类型:
元素选择器
通过 HTML 元素名称匹配元素:
css
p {
color: #333;
}
div {
margin: 10px;
}
类选择器
通过元素的 class
属性值匹配元素,以 .
开头:
css
.button {
padding: 8px 16px;
}
.highlight {
background-color: yellow;
}
ID 选择器
通过元素的 id
属性值匹配元素,以 #
开头(一个文档中 ID 应唯一):
css
#header {
height: 60px;
}
#logo {
width: 120px;
}
通用选择器
匹配文档中的所有元素,以 *
表示:
css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
属性选择器
根据元素的属性及属性值匹配元素:
css
/* 匹配具有 title 属性的元素 */
[title] {
border: 1px dotted #ccc;
}
/* 匹配 href 属性值为 "https://example.com" 的元素 */
a[href="https://example.com"] {
color: #0066cc;
}
/* 匹配 class 属性值包含 "menu" 的元素 */
[class*="menu"] {
display: flex;
}
属性选择器支持多种匹配模式:
[attr]
:存在指定属性[attr=value]
:属性值等于指定值[attr~=value]
:属性值包含指定单词[attr|=value]
:属性值以指定值开头(或后跟连字符)[attr^=value]
:属性值以指定值开头[attr$=value]
:属性值以指定值结尾[attr*=value]
:属性值包含指定子串
组合选择器
组合选择器用于选择满足特定关系的元素:
后代选择器
选择祖先元素内的所有后代元素,使用空格分隔:
css
/* 选择 .container 内的所有 p 元素 */
.container p {
line-height: 1.6;
}
子选择器
选择父元素的直接子元素,使用 >
分隔:
css
/* 选择 ul 的直接子元素 li */
ul > li {
list-style: none;
}
相邻兄弟选择器
选择紧接在指定元素后的兄弟元素,使用 +
分隔:
css
/* 选择 h2 后面紧接的 p 元素 */
h2 + p {
font-weight: bold;
}
通用兄弟选择器
选择指定元素后的所有兄弟元素,使用 ~
分隔:
css
/* 选择 .feature 后面的所有 .description 元素 */
.feature ~ .description {
margin-left: 20px;
}
伪类选择器
伪类用于定义元素的特殊状态,以 :
开头:
状态伪类
css
/* 未访问的链接 */
a:link {
color: blue;
}
/* 已访问的链接 */
a:visited {
color: purple;
}
/* 鼠标悬停时 */
a:hover {
text-decoration: underline;
}
/* 元素被激活时 */
a:active {
color: red;
}
/* 获得焦点的元素 */
input:focus {
border-color: #66afe9;
}
结构伪类
css
/* 选择第一个子元素 */
li:first-child {
border-top: 1px solid #eee;
}
/* 选择最后一个子元素 */
li:last-child {
border-bottom: 1px solid #eee;
}
/* 选择第 n 个子元素(n 从 1 开始) */
tr:nth-child(2n) {
background-color: #f9f9f9;
}
/* 选择没有子元素的元素 */
div:empty {
display: none;
}
其他常用伪类
css
/* 选择当前选中的元素 */
:target {
background-color: #fff3cd;
}
/* 选择不匹配指定选择器的元素 */
:not(.exclude) {
opacity: 1;
}
/* 选择启用状态的元素 */
button:enabled {
cursor: pointer;
}
/* 选择禁用状态的元素 */
button:disabled {
opacity: 0.7;
}
伪元素选择器
伪元素的特定部分设置样式,以 ::
开头:
css
/* 选择元素的第一个字母 */
p::first-letter {
font-size: 1.5em;
font-weight: bold;
}
/* 选择元素的第一行 */
p::first-line {
text-transform: uppercase;
}
/* 在元素内容前插入内容 */
.badge::before {
content: "New: ";
font-weight: bold;
}
/* 在元素内容后插入内容 */
.price::after {
content: " $";
}
/* 选择元素的高亮部分 */
::selection {
background-color: #b3d4fc;
}
选择器优先级
当多个选择器匹配同一个元素时,优先级决定了哪个样式规则会被应用。优先级可以理解为一个四元组 (a, b, c, d)
,优先级从高到低依次比较:
- 内联样式 (a):元素的
style
属性中的样式,优先级最高 - ID 选择器 (b):每个 ID 选择器贡献 1 分
- 类选择器、属性选择器、伪类 (c):每个该类型选择器贡献 1 分
- 元素选择器、伪元素 (d):每个该类型选择器贡献 1 分
优先级计算示例
css
/* (0, 0, 0, 1) */
p { . . . }
/* (0, 0, 1, 0) */
.class { . . . }
/* (0, 0, 1, 1) */
p.class { . . . }
/* (0, 1, 0, 0) */
#id { . . . }
/* (0, 1, 1, 1) */
div#id .class { . . . }
/* (1, 0, 0, 0) - 内联样式 */
/* style 属性中的样式 */
重要规则
!important
可以覆盖任何优先级,但应谨慎使用- 相同优先级时,后定义的规则会覆盖先定义的规则
- 通用选择器 (
*
)、组合符 (+
,>
,~
, 空格) 不影响优先级 - 通配符属性选择器
[attr]
与类选择器优先级相同
css
/* 即使类选择器后定义,!important 仍会优先 */
p {
color: red !important;
}
.highlight {
color: blue;
}
最佳实践
- 优先使用低优先级选择器:减少 ID 选择器和
!important
的使用,提高样式的可复用性 - 保持选择器简洁:避免过度嵌套,提高性能和可维护性
- 使用类设计组件:采用 BEM 等命名规范,使选择器既明确又具有适当优先级
- 避免内联样式:便于维护和覆盖,分离结构与样式