移动端box-shadow“显脏”主因是高DPI屏下亚像素渲染敏感,导致模糊半径过大+透明度过高(如rgba(0,0,0,0.15))引发边缘发灰;应改用整数参数、负spread-radius及双层阴影(如0 1px 2px -1px rgba(0,0,0,0.06), 0 4px 8px -2px rgba(0,0,0,0.08)),并配合transform触发合成层。

移动端box-shadow为什么“显脏”而不是“显浮”
不是阴影加得不够重,而是高DPI屏幕(如iPhone 15 Pro、Pixel 8)对亚像素渲染极其敏感:box-shadow: 0 4px 12px rgba(0,0,0,0.15) 这类桌面端惯用值,在Safari里会因模糊半径过大+透明度偏高,导致边缘发灰、色块浑浊,视觉上像蒙了层雾,而非干净的投影。
- blur-radius超过4px时,iOS Safari会放大渲染误差,尤其在浅色背景上更明显
- rgba(0,0,0,0.15)在白色背景上已接近“脏灰”,实测0.08~0.1之间才是安全区间
- 父容器若设了
overflow: hidden,阴影会被裁剪——但用户看不到裁剪过程,只觉得“阴影变弱了”
写法必须改:整数参数 + 负spread + 多层分拆
别再用单层大模糊。移动端真正清晰的阴影靠三件事:数值全取整、用负spread-radius收束边缘、至少两层阴影模拟近光+远光。
- 第一层(紧贴卡片):
0 1px 2px -1px rgba(0,0,0,0.06)—— 负spread让阴影不“虚胖”,适合小卡片 - 第二层(主投影):
0 4px 8px -2px rgba(0,0,0,0.08)—— 垂直偏移加大,模糊略增,但spread仍为负 - 两层叠加写法:
box-shadow: 0 1px 2px -1px rgba(0,0,0,0.06), 0 4px 8px -2px rgba(0,0,0,0.08); - 绝对不要出现
0.5px、1.2px这类非整数值,Safari对它们的渲染完全不可控
hover状态必须加transform,不能只调box-shadow
只改box-shadow会让卡片看起来“变重”,不是“抬升”。用户手指点下去需要的是物理反馈感,不是颜色加深。
- 基础态:
transform: translateY(0); box-shadow: ... - hover态:
transform: translateY(-3px); box-shadow: 0 3px 6px -1px rgba(0,0,0,0.1), 0 6px 12px -3px rgba(0,0,0,0.12); - 过渡必须限定属性:
transition: transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94), box-shadow 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94); - 切忌写
transition: all——它会监听width/height等无关属性,一滚动就触发重排,卡顿明显
移动端点击无反应?别碰:hover,改用JS或语义化标签
iOS Safari和Android Chrome根本不把:hover当触控主交互模式。点十次,阴影可能一次都不动。
- 最简方案:把换成
,并加cursor: pointer和outline: none(但保留:focus-visible样式供键盘用户)- 可控方案:用JS监听
touchstart,动态加.is-pressed类,CSS里写.card.is-pressed { ... }- 别信
@media (hover: hover)——iOS Safari对它的支持极不稳定,多数机型直接忽略- 如果卡片本身有
overflow: hidden,记得外层包一层position: relative容器,否则阴影永远出不来真实项目里最容易被跳过的是合成层触发。哪怕参数全对,没加
transform: translateZ(0)或will-change: transform,iOS Safari仍可能把阴影画成一团糊。这不是bug,是它的渲染策略——你得主动告诉它:“这个元素要动,给它单独开个图层”。 - 可控方案:用JS监听
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











