
CSS选择器是前端开发中最基础也是最重要的概念之一。它们不仅决定了样式规则将应用于哪些元素,还通过特异性规则决定了当多个规则冲突时哪个规则将生效。 本文将全面解析CSS选择器的类型、用法、优先级计算以及最佳实践,帮助你掌握CSS选择器的核心知识,写出更高效、更易维护的样式代码。
CSS选择器基础
CSS选择器是用于"选择"要设置样式的HTML元素的模式。选择器可以根据元素的标签名、类名、ID、属性、状态等多种条件来选择元素。
/* 元素选择器 */
p {
color: #333;
}
/* 类选择器 */
.highlight {
background-color: yellow;
}
/* ID选择器 */
#header {
padding: 20px;
}
/* 通用选择器 */
* {
box-sizing: border-box;
}
/* 属性选择器 */
[type="text"] {
border: 1px solid #ccc;
}
/* 分组选择器 */
h1, h2, h3 {
font-family: 'Arial', sans-serif;
}
选择器演示
基本选择器是CSS中最常用的选择器类型:
- 元素选择器:根据HTML标签名选择元素
- 类选择器:根据class属性选择元素,以点号(.)开头
- ID选择器:根据id属性选择元素,以井号(#)开头
- 通用选择器:选择所有元素,以星号(*)表示
- 属性选择器:根据属性或属性值选择元素
- 分组选择器:同时选择多个元素,用逗号分隔
组合选择器与关系选择器
组合选择器允许你基于元素之间的关系选择元素,这对于创建精确的样式规则非常有用。
/* 后代选择器 (空格) */
.container p {
margin-bottom: 10px;
}
/* 子选择器 (>) */
.menu > li {
display: inline-block;
}
/* 相邻兄弟选择器 (+) */
h2 + p {
margin-top: 5px;
}
/* 通用兄弟选择器 (~) */
h2 ~ p {
color: #666;
}
/* 组合使用示例 */
#main .content > h2.special + p {
font-size: 1.2em;
color: blue;
}
HTML结构示例
<div class="container"> <h2>标题</h2> <p>第一个段落</p> <div class="content"> <p>嵌套段落</p> <ul> <li>列表项1</li> <li>列表项2</li> </ul> </div> <p>另一个段落</p> </div>
.container p 选择所有.container内的p元素
.container > p 只选择直接子元素p
h2 + p 选择紧接在h2后面的p
h2 ~ p 选择h2后面的所有p
关系选择器提供了强大的元素定位能力:
- 后代选择器:选择所有后代元素(包括嵌套多层的元素)
- 子选择器:只选择直接子元素
- 相邻兄弟选择器:选择紧接在另一个元素后的元素
- 通用兄弟选择器:选择所有在指定元素之后的兄弟元素
伪类与伪元素选择器
伪类和伪元素选择器允许你选择DOM中不直接存在的元素或状态,为样式添加更多动态效果和精细控制。
常用伪类选择器
a:link { color: blue; } /* 未访问的链接 */
a:visited { color: purple; } /* 已访问的链接 */
a:hover { color: red; } /* 鼠标悬停 */
a:active { color: green; } /* 激活的链接 */
/* 表单相关伪类 */
input:focus {
border-color: blue;
box-shadow: 0 0 5px rgba(0, 0, 255, 0.5);
}
input:disabled {
background-color: #eee;
}
input:checked {
background-color: blue;
}
/* 结构伪类 */
li:first-child { font-weight: bold; }
li:last-child { border-bottom: none; }
li:nth-child(2n) { background-color: #f5f5f5; } /* 偶数行 */
li:nth-child(2n+1) { background-color: white; } /* 奇数行 */
p:first-of-type { font-size: 1.2em; }
p:last-of-type { margin-bottom: 0; }
伪元素选择器
p::first-line {
font-weight: bold;
color: #333;
}
p::first-letter {
font-size: 2em;
float: left;
margin-right: 5px;
}
.content::before {
content: "▶";
color: green;
margin-right: 5px;
}
.content::after {
content: "";
display: block;
height: 1px;
background-color: #ccc;
margin: 10px 0;
}
::selection {
background-color: yellow;
color: black;
}
伪元素演示
▶ 这 是一段演示文本,展示了伪元素的使用效果。第一行使用了::first-line伪元素,首字母使用了::first-letter伪元素,前面添加了::before内容。
尝试选择一些文本看看::selection效果。
::before 在元素前插入内容
::after 在元素后插入内容
::first-letter 选择首字母
::selection 选择用户选中的文本
CSS选择器优先级
当多个CSS规则应用于同一个元素时,浏览器使用优先级规则来确定哪个规则将生效。理解优先级是掌握CSS的关键。
优先级计算规则
/* 特异性值: 0,0,0,1 */
p { color: black; }
/* 特异性值: 0,0,1,0 */
.text { color: blue; }
/* 特异性值: 0,1,0,0 */
#content { color: green; }
/* 特异性值: 0,0,1,1 */
p.text { color: purple; }
/* 特异性值: 0,1,1,1 */
#content p.text { color: red; }
/* 内联样式: 1,0,0,0 */
<p style="color: orange;">...</p>
/* !important 最高优先级 */
p { color: yellow !important; }
优先级计算器
优先级计算规则:
a,b,c,d 其中:
- a: 内联样式 (1 或 0)
- b: ID选择器的数量
- c: 类、伪类和属性选择器的数量
- d: 元素和伪元素选择器的数量
优先级规则总结
- !important 声明具有最高优先级
- 内联样式 优先级高于任何选择器
- ID选择器 优先级高于类和属性选择器
- 类选择器、属性选择器和伪类 优先级高于元素选择器
- 相同特异性时,后定义的规则 会覆盖先定义的规则
- 通用选择器(*)和继承的值对特异性没有影响
/* 特异性: 0,0,0,1 */
p { color: blue; }
/* 特异性: 0,0,1,0 - 这个会生效 */
.intro { color: red; }
/* 特异性: 0,0,1,1 - 这个会覆盖上面的.red */
p.intro { color: green; }
/* 特异性: 0,1,0,0 - 这个会覆盖上面的所有 */
#main { color: purple; }
/* 特异性: 0,1,0,1 - 这个会覆盖上面的#main */
#main p { color: orange; }
/* 使用!important - 最高优先级 */
p { color: black !important; }
最佳实践与常见错误
CSS选择器最佳实践
- 使用类选择器而不是ID选择器,以提高可重用性和降低特异性
- 保持选择器简单且具体,避免过度嵌套
- 使用语义化的类名,而不是表现形式的类名
- 避免使用!important,除非绝对必要
- 利用CSS变量和现代布局技术减少对复杂选择器的需求
- 使用BEM等方法论来组织CSS类和选择器
常见错误与解决方法
.header .nav .menu .item .link {
color: blue;
}
/* 解决: 使用更简单的类名 */
.menu-link {
color: blue;
}
/* 错误: 过度依赖ID选择器 */
#header #nav #menu #item {
padding: 10px;
}
/* 解决: 使用类选择器 */
.menu-item {
padding: 10px;
}
/* 错误: 滥用!important */
.button {
background-color: blue !important;
}
/* 解决: 提高选择器特异性或重构CSS */
.primary-button {
background-color: blue;
}
性能考虑
虽然现代浏览器对CSS选择器的处理非常高效,但仍然应该注意:
- 避免使用通用选择器作为关键选择器(最右边的选择器)
- 避免使用属性选择器进行模糊匹配,如[class*="box"]
- 尽量减少选择器的复杂度和数量
- 使用继承和层叠来减少重复规则