box-shadow悬停“跳变”因未声明transition导致突变;应同时为box-shadow和transform加相同transition,避免none值、多层阴影及无效translatez,控制模糊半径≤12px,并用@media(hover:hover)适配触摸设备。

box-shadow 悬停变深时为什么影子“跳变”不自然
直接改 box-shadow 的数值(比如从 0 2px 4px rgba(0,0,0,0.1) 切到 0 10px 20px rgba(0,0,0,0.3))会触发浏览器重绘+重排,尤其当阴影模糊半径和偏移量同时突变,人眼明显感知“咔哒”一下跳过去。关键不是不能改,而是没告诉浏览器“这个变化要缓动”。
实操建议:
- 必须给
box-shadow和transform同时加transition,且用相同持续时间和缓动函数,例如:transition: box-shadow 0.3s ease, transform 0.3s ease; - 避免在悬停态中写多个
box-shadow值(如内阴影+外阴影混用),多层阴影叠加会让过渡帧计算更吃力,移动端易卡顿 - 初始态的
box-shadow不要设为none,而用极小值替代,比如0 1px 2px rgba(0,0,0,0.05),否则部分 Safari 会丢过渡帧
translateZ 在纯 CSS 中实际无效,该用 translateY
translateZ() 只在有 3D 上下文(transform-style: preserve-3d 且父容器有 perspective)时才起作用,但卡片升起是平面视觉效果,强行套 3D 反而增加渲染负担、引发 iOS Safari 渲染异常(比如阴影错位或闪烁)。
实操建议:
- 用
transform: translateY(-4px)模拟“升起”,配合box-shadow加深,视觉上足够可信 - 如果真要轻微透视感,只给父容器加
perspective: 600px,卡片自身仍用translateY,不要加translateZ - 注意:Chrome 115+ 对
transform属性的硬件加速策略变了,translateY仍稳,但translateZ在无perspective下会被降级为软件渲染
hover 卡片在触摸设备上不触发怎么办
CSS :hover 在 iOS 和 Android 大部分浏览器里默认只对可点击元素(如 <a></a>、<button></button>)生效,普通 <div> 卡片悬停根本不会响应——这不是 bug,是浏览器为省电做的主动限制。
<p>实操建议:</p>
<ul>
<li>给卡片容器加 <code>cursor: pointer,部分安卓 Chrome 会因此启用 hover
@media (hover: hover) 做渐进增强:@media (hover: hover) {
.card:hover {
transform: translateY(-4px);
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}
}
touchstart + mouseenter,动态切 class;但要注意避免双触发(iOS 上 touchstart 后紧跟着 mouseenter)阴影加深太多导致文字发虚或边缘晕开
当 box-shadow 模糊半径(第二个值)超过 12px,尤其在高 DPR 屏幕(如 MacBook Retina、iPhone)上,文字边缘会出现明显柔化,像蒙了层灰雾——这是浏览器对大模糊阴影做抗锯齿时的副作用,并非代码写错。
实操建议:
- 控制最大模糊半径在
12px内,优先加大偏移量(第一个值)和颜色透明度来强化立体感,例如:0 8px 12px rgba(0,0,0,0.25)比0 4px 20px rgba(0,0,0,0.25)更锐利 - 对文字内容区域单独加
backface-visibility: hidden,能减少部分浏览器的字体渲染模糊 - 若设计稿强制要求浓重阴影,接受它在高分屏上的轻微发虚——比硬塞
filter: blur(0)强制重绘更稳妥,后者可能引发闪屏
transition,在旧 iPad 上卡顿,在新 Mac 上丝滑,中间差的不是代码,是渲染管线对 transform 和 box-shadow 的不同优化路径。











