CSS 选择器详解
从基础到进阶,全面掌握 CSS 选择器的使用与优先级规则
引言
基础选择器
- 元素选择器
- 类选择器(class)
- ID 选择器
- 通配符选择器
当选择器同时作用时,到底哪个会生效?
答案是ID选择器
这不是因为ID选择牌子最后执行导致的覆盖,,只是选择器的优先级不同导致的,当我们调整顺序后结果依然不变
组合器与关系选择
- 后代选择器
- 子选择器(
>) - 相邻兄弟选择器(
+) - 通用兄弟选择器(
~)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>选择器</title>
<style>
/* 直接相连选择器 */
/* h1后面相邻的兄弟p */
h1 + p{
color:red ;
}
p + p{
color: green;
}
/* h1后面所有的兄弟p */
h1 ~p{
color: blue;
}
/* 子元素选择器 */
.container > p{
color: pink;
}
/* 后代选择器 */
.container p{
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<p>这是0段文字</p>
<h1>标题</h1>
<p>这是第一段文字。</p>
<p>这是第二段文字。</p>
<a href="#">链接</a>
<span>这是一个span元素。</span>
<div class="inner">
<p>这是内部段落。</p>
</div>
</div>
</body>
</html>
.container p作为后代选择器,会选择所有对应类名中所有p标签
.container >p作为子元素选择器,只会选择子级元素,不会影响其他后代(正如图中显示的内部段落并未改变)
h1 + p是相邻兄弟选择器,只会选择h1标签后面第一个相邻的兄弟p标签
h1 ~p是通用兄弟选择器,它会选择h1之后所有的p兄弟标签
伪类选择器
:hover(鼠标悬停):focus(光标聚集):active(鼠标点击):nth-child():nth-of-type()
这类选择器通常需要达成一定的条件才能实现样式
对于
:nth-child()和:nth-of-type()我们以下面这个案列解释他们的不同
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container p:nth-child(1) {
background-color: yellow;
color: black;
}
.container p:nth-of-type(3) {
background-color: red;
color: black;
}
</style>
</head>
<body>
<div class="container">
<h1>nth-child vs nth-of-type</h1>
<p>这是一个段落。</p>
<div>这是一个div。</div>
<p>这是第二个段落。</p>
<p>这是第三个段落。</p>
<div>这是第二个div。</div>
</div>
</body>
</html>
- 对于
.container p:nth-child(1)它会找到container类名标签中的第一个标签且标签为<p>的元素,二者必须同时成立否则不会生效。
示例 ---- 第一个标签为<h1>,不生效
- 对于
.container p:nth-of-type(3),它会找到container类名标签的子标签中第三个<p>标签生效,注意是第三个<p>标签而非第三个标签。
伪元素选择器
::before::after::first-line::first-letter
伪元素用于向元素的特定部分添加样式,它们并不对应真实的 DOM 节点,而是 CSS 渲染层面上的“虚拟”内容。
::before和::after必须配合content属性使用,常用于插入图标、装饰性内容或清除浮动。::first-line可以为块级元素的第一行文本设置特殊样式(如首行缩进、字体变化)。::first-letter常用于实现“首字下沉”效果,适用于段落、标题等文本容器。
注意:伪元素使用双冒号
::以区别于伪类(单冒号:),这是 CSS3 的规范写法,尽管浏览器仍兼容单冒号形式。
<!-- 示例:使用 ::before 添加图标 -->
<p class="note">这是一条提示信息</p>
<style>
.note::before {
content: "💡 ";
color: gold;
}
</style>
选择器优先级(Specificity)
-
优先级计算规则(个十百千)
CSS 选择器的优先级按 内联样式(1,0,0,0) > ID(0,1,0,0) > 类/伪类/属性(0,0,1,0) > 元素/伪元素(0,0,0,1) 计算,从右到左依次为:
千位:内联样式
百位:ID 选择器数量
十位:类、伪类、属性选择器数量
个位:元素与伪元素选择器数量比较时从高位到低位逐位比较,数值大者胜出。
-
!important的影响
!important会覆盖任何其他声明(包括内联样式),但会破坏样式的可维护性,应尽量避免使用。 -
内联样式 vs 外部样式
内联样式(写在style属性中)天然具有更高优先级(1000),但不利于复用和维护,建议仅在必要时使用。
优先级不是由书写顺序决定的,而是由选择器类型决定。即使把低优先级的规则写在后面,高优先级规则依然生效。
常见误区与注意事项
-
inline元素对某些 CSS 属性的支持限制
行内元素(如<span>、<a>)无法设置width、height、margin-top/bottom等盒模型属性,若需使用,应将其转换为inline-block或block。 -
避免滥用
!important
过度使用!important会导致样式难以调试和覆盖,应通过合理设计选择器结构和优先级来解决问题。
实战示例
例如,实现这样的效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>伪元素</title>
<style>
.container{
max-width: 600px;/*适配 移动端用自己的宽度 PC端 mw*/
margin: 0 auto;/* 左右水平居中*/
padding: 20px;
font-family:Arial, Helvetica, sans-serif ;
}
h1{
text-align: center;
}
p{
line-height: 1.6;
}
.more{
/* CSS格式化上下文 定义元素的布局规则*/
display: inline-block;
padding: 10px 20px;
background-color: blue;
color: white;
text-decoration: none;
position: relative;
transition: all .3s ease;
}
.more::before{
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 12px;
background-color:red;
transform: scaleX(0);
transform-origin: bottom left;
transition: transform .3s ease;
}
.more:hover::before{
transform: scaleX(1);
/* transform-origin: bottom left; */
}
.more::after{
display: inline-block;
content: '\2192';
margin-left: 5px;
transition: transform .3s ease;
}
.more:hover::after{
transform: translateX(5px);
}
</style>
</head>
<body>
<div class="container">
<h1>示例标题</h1>
<p>这是一个段落</p>
<a href="#" class="more">查看更多</a>
</div>
</body>
</html>
通过组合多种选择器,可以精准控制页面任意元素的样式表现。
结语
CSS 选择器是样式控制的基石。掌握其分类、组合方式及优先级规则,不仅能写出更高效、可维护的代码,还能避免大量“为什么样式没生效”的调试困扰。理解每一个选择器背后的逻辑,比死记硬背更重要。多写、多试、多观察,你将真正驾驭 CSS 的力量。