CSS伪类和伪元素完全指南::hover、:before这些到底有什么区别?
🧑🏫 作者:全栈老李
📅 更新时间:2025 年 5 月
🧑💻 适合人群:前端初学者、进阶开发者
🚀 版权:本文由全栈老李原创,转载请注明出处。
大家好,我是全栈老李。今天咱们来聊聊CSS中那些让人又爱又恨的伪类和伪元素,很多同学用了好几年CSS,可能还是分不清:hover和:before到底有什么区别。别急,今天老李就带大家彻底搞明白这个知识点。
伪类和伪元素到底是个啥?
想象一下,你正在参加一个化妆舞会。伪类就像是给已经存在的你(DOM元素)戴上不同的面具——比如”开心”面具、”生气”面具,而你的本质没变;伪元素则像是给你凭空变出一个伴舞者,这个伴舞者本来不存在,是CSS帮你创造出来的。
从技术角度说,伪类(Pseudo-class)用于选择元素的特定状态,而伪元素(Pseudo-element)则用于在元素中创建并样式化某些”虚拟”的部分。
伪类:元素的状态选择器
伪类以单冒号(:)开头,用来选择元素的特定状态。比如:
:hover – 鼠标悬停时的状态
:active – 元素被激活(比如点击)时的状态
:focus – 元素获得焦点时的状态
:nth-child() – 选择特定位置的子元素
/* 全栈老李提示:这是典型的伪类使用示例 */
button:hover {
background-color: #4CAF50; /* 鼠标悬停时按钮变绿 */
transform: scale(1.05); /* 轻微放大效果 */
}
伪元素:元素的虚拟部分
伪元素以双冒号(::)开头(虽然单冒号也支持,但推荐用双冒号),用于创建并样式化元素的特定部分:
::before – 在元素内容前插入内容
::after – 在元素内容后插入内容
::first-letter – 选择元素的第一个字母
::selection – 选择用户选中的文本
/* 全栈老李提示:伪元素常用于装饰性内容 */
blockquote::before {
content: "“"; /* 在引用前添加左引号 */
font-size: 3em;
color: #ccc;
}
为什么需要区分它们?
理解伪类和伪元素的区别很重要,因为:
选择的目标不同:伪类选择的是元素的某种状态,伪元素选择的是元素的某个部分
DOM表现不同:伪类不会影响DOM结构,伪元素会在DOM中创建虚拟节点
使用场景不同:伪类常用于交互反馈,伪元素常用于装饰性内容
真实代码示例
让我们看一个结合伪类和伪元素的完整例子:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>全栈老李的CSS演示</title>
<style>
/* 伪类示例 */
.fancy-button {
padding: 12px 24px;
background: linear-gradient(to right, #ff8a00, #da1b60);
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
/* 全栈老李提示:这里用了多个伪类 */
.fancy-button:hover {
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}
.fancy-button:active {
transform: translateY(-1px);
box-shadow: 0 5px 10px rgba(0,0,0,0.2);
}
/* 伪元素示例 */
.fancy-button::after {
content: "";
display: inline-block;
height: 100%;
width: 100%;
border-radius: 4px;
position: absolute;
top: 0;
left: 0;
background: linear-gradient(to right, #da1b60, #ff8a00);
z-index: -1;
transition: opacity 0.3s ease;
opacity: 0;
}
.fancy-button:hover::after {
opacity: 1;
}
/* 组合使用示例 */
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted black;
}
.tooltip:hover::before {
content: attr(data-tooltip);
position: absolute;
width: 200px;
background-color: #555;
color: #fff;
text-align: center;
padding: 5px;
border-radius: 6px;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -100px;
opacity: 0;
transition: opacity 0.3s;
}
.tooltip:hover::before {
opacity: 1;
}
</style>
</head>
<body>
<button class="fancy-button">悬停看我效果</button>
<div class="tooltip" data-tooltip="这是全栈老李的提示框">鼠标悬停显示提示</div>
</body>
</html>
常见使用场景
伪类的典型应用
交互反馈::hover, :active, :focus 用于按钮、链接等交互元素
表单状态::checked, :disabled, :valid 用于表单元素
结构选择::nth-child(), :first-child, :last-child 用于选择特定位置的元素
/* 全栈老李提示:表单状态伪类示例 */
input:focus {
border-color: #4CAF50;
box-shadow: 0 0 5px rgba(76, 175, 80, 0.5);
}
input:invalid {
border-color: #f44336;
}
/* 结构伪类示例 */
li:nth-child(odd) {
background-color: #f2f2f2;
}
伪元素的典型应用
装饰性内容:::before, ::after 用于添加图标、引号等
文本特效:::first-letter, ::first-line 用于首字母大写或首行样式
自定义选中样式:::selection 改变文本选中时的样式
/* 全栈老李提示:伪元素装饰示例 */
.price::before {
content: "¥";
color: #f44336;
margin-right: 4px;
}
/* 首字母下沉效果 */
article p::first-letter {
font-size: 3em;
float: left;
line-height: 1;
margin-right: 8px;
color: #4CAF50;
}
/* 自定义选中样式 */
::selection {
background: #4CAF50;
color: white;
}
高级技巧与注意事项
伪元素必须设置content属性:即使是空字符串content: ""也要设置,否则不会显示
伪类可以链式使用:比如a:hover:focus选择同时悬停和获得焦点的链接
性能考虑:过度复杂的伪类选择器(如深层嵌套)可能影响性能
伪元素默认是行内元素:可以通过display属性改变
/* 全栈老李提示:伪元素的高级用法 */
.card {
position: relative;
background: white;
padding: 20px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.card::after {
content: "";
position: absolute;
z-index: -1;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: inherit;
transform: rotate(2deg);
filter: blur(4px);
opacity: 0.7;
}
面试题时间
题目:实现一个CSS函数,当传入一个数字n时,生成一个n×n的网格布局,其中奇数行背景为浅灰色(#f5f5f5),偶数行背景为白色,并且每个单元格在悬停时有放大效果。使用纯CSS实现,不能使用JavaScript。
要求:
使用SCSS或CSS变量实现
网格间距为10px
悬停放大比例为1.1倍
过渡时间为0.3秒
示例输出(当n=3时):
<div class="grid-container">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
提示:可以使用:nth-child()伪类和CSS变量来实现。
同学们可以把你们的答案写在评论区,我会随机抽几位同学的答案进行点评哦~全栈老李期待看到你们的创意解决方案!
好了,今天的CSS伪类和伪元素指南就到这里。记住,伪类是给元素戴面具,伪元素是给元素找伴舞。理解了这个本质区别,用起来就得心应手了。我是全栈老李,我们下期再见!
🔥 必看面试题
【3万字纯干货】前端学习路线全攻略!从小白到全栈工程师(2025版)
【初级】前端开发工程师面试100题(一)
【初级】前端开发工程师面试100题(二)
【初级】前端开发工程师的面试100题(速记版)
我是全栈老李,一个资深Coder!
写码不易,如果你觉得本文有收获,点赞 + 收藏走一波!感谢鼓励🌹🌹🌹


















暂无评论内容