伪类匹配元素状态(如:hover),伪元素匹配dom外虚拟内容(如::before);::before必须设content才显示,:hover::before合法而::before:hover非法,transition须加在触发状态的父元素上。

伪类和伪元素根本不是一回事,别混着用
伪类(比如 :hover)匹配的是元素的某种状态,伪元素(比如 ::before)匹配的是元素内部“不存在于DOM中”的虚拟内容。浏览器解析时,它们的语法、作用时机、可继承性都不同——:hover 是条件触发,::before 是内容注入。
为什么 :hover::before 能生效,但 ::before:hover 报错
::before 生成的是一个**匿名盒子**,它没有自己的状态,不能被用户交互直接触发。所以你永远写不出 ::before:hover,CSS会直接忽略整条规则(DevTools里显示为无效)。而 :hover::before 的意思是:“当父元素处于 hover 状态时,渲染它的 ::before”。
- 合法:
a:hover::before - 非法:
a::before:hover(语法错误,浏览器不认) - 注意:旧写法
:before(单冒号)在 CSS2 中允许,但现代规范强制双冒号::before表示伪元素,单冒号只留给伪类
::before 和 ::after 必须配 content 才能显示
这是最常踩的坑:写了 div::before { background: red; width: 20px; },结果什么都没出来。因为没设 content,伪元素默认是 content: none,压根不生成盒模型。
-
content: ""是最常用写法(空字符串,但盒子存在) -
content: "★"可插入文字或符号 -
content: attr(data-label)可读取 HTML 属性值 - 没有
content,其他样式(display、width、background)全无效
用 :hover 控制 ::before 动画时,别忘了加 transition 到父元素上
动画效果要生效,必须把 transition 写在**触发状态的元素上**(即带 :hover 的那个选择器),而不是写在 ::before 自己身上——因为伪元素不能单独监听状态变化。
button {
position: relative;
}
button::before {
content: "";
position: absolute;
width: 0;
height: 2px;
background: #007bff;
bottom: 0;
}
button:hover::before {
width: 100%;
}
button {
transition: all 0.3s ease; /* ✅ 这里加 transition */
}
如果把 transition: width 0.3s 写在 button::before 规则里,大多数浏览器不会触发过渡(Chrome 有部分支持,但 Safari/Firefox 不稳定)。
伪元素的盒模型行为和真实元素不完全一致——比如它默认是 inline-level,width/height 需配合 display: block 或 inline-block 才有效;而伪类只是开关,不产生新盒子。这点在调试布局错位时特别容易漏掉。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











