hover伪类必须直接写在被悬停的元素选择器上,如.card:hover;若隔层写(如.card .title:hover)则仅作用于子元素,且父元素不可见或pointer-events: none时hover失效。

hover伪类写在哪?别套错选择器层级
直接写:hover没反应,大概率是选择器没命中目标元素。它必须紧贴被悬停的元素本身,不能隔层代理——比如.card:hover .title可以,但.card .title:hover只对.title生效,和父容器无关。
- 常见错误:给父容器加
display: none或visibility: hidden后还指望子元素能触发:hover——不行,不可见元素不参与交互 - 注意继承:如果父元素设了
pointer-events: none,子元素哪怕显式写了pointer-events: auto,hover也可能失效(部分浏览器行为不一致) - 移动端无hover:iOS Safari 和 Android Chrome 在触摸设备上仅对
<a></a>等可聚焦元素触发一次:hover,别依赖它做核心交互
transition动画卡顿?检查触发属性和硬件加速
只写transition: all 0.3s是最容易翻车的操作。浏览器对某些CSS属性的重绘开销极大,比如height、width、top/left会触发布局(layout),而transform和opacity走合成层(compositor),更顺滑。
- 推荐写法:
transition: transform 0.2s ease, opacity 0.2s ease,避免all - 如果必须用
background-color,确保颜色值是RGB或十六进制,别用hsl()或rgba()混用——部分旧版Chrome在插值时会掉帧 - 极端情况可加
will-change: transform提前提示,但别滥用,会增加内存占用
hover和:focus同时存在时样式冲突怎么解?
键盘用户Tab到按钮,再鼠标移入,:hover和:focus会同时生效。如果两个状态样式互相覆盖,得靠伪类顺序控制优先级——CSS里后声明的规则胜出。
- 正确顺序:
:link → :visited → :hover → :active → :focus(即:focus放最后,确保焦点态不被hover吃掉) - 若需hover+focus共存高亮,直接写组合选择器:
button:hover:focus,比单独写更可控 - 注意可访问性:纯
:hover显示的提示文字(如tooltip),务必补充:focus-within或:focus支持,否则键盘用户看不到
伪类嵌套在CSS-in-JS或预处理器里要注意什么?
像styled-components或SCSS里写&:hover看着方便,但实际生成的CSS选择器权重可能变高,和全局样式打架。
立即学习“前端免费学习笔记(深入)”;
- SCSS中
.btn { &:hover { ... } }编译出来是.btn:hover,没问题;但.btn:hover { .icon { ... } }会生成.btn:hover .icon,层级加深,可能覆盖不到预期元素 - styled-components里
css块内用&:hover是安全的,但别在asChild或forwardRef组件里动态拼接伪类,运行时无法保证选择器稳定性 - 最稳妥的做法:hover样式尽量扁平化,避免多层嵌套,用明确类名代替深度选择器










