按钮必须挂载在body顶层且祖先无transform等触发层叠上下文的属性,否则会被截断;投影优先用box-shadow,悬浮动画慎用scale和all过渡,移动端需适配safe-area-inset-bottom并保证48px点击区域。

按钮挂载位置错误导致投影被截断
卡片布局里直接写 <button>,投影再漂亮也白搭——它会被父容器的 overflow: hidden、transform 或非 auto 的 z-index 层叠上下文吞掉。常见现象是:鼠标悬停时阴影只显示半截,或者完全点不中按钮。
- 必须把按钮节点直接放在
<body>最顶层,和卡片容器平级,不能嵌套在<div class="card-grid">之类结构里 - 检查按钮所有祖先元素,禁用
transform、filter、will-change——哪怕只加了一行scale(1)都会新建层叠上下文 - React/Vue 中若用 Portal 挂载,确保 Portal 容器本身没被包裹在带层叠上下文的组件内
投影用 box-shadow 还是 Canvas?
纯 CSS 卡片悬浮投影,box-shadow 足够且更轻量;Canvas 动态投影适合需要随鼠标实时偏移光源的高级场景,但代价是复杂度陡增、移动端兼容性差、动画易掉帧。
- 常规需求用
box-shadow:hover 时加大blur和offset,比如box-shadow: 0 6px 16px rgba(0,0,0,0.15) - 别用
margin-top或top实现“上浮”,会触发重排,卡片网格抖动;改用transform: translateY(-4px) - Canvas 方案仅当需模拟真实光源(如阴影角度随鼠标移动)才考虑,否则属于过度设计
transform 和 transition 组合踩坑点
悬浮动画卡顿、点击区域跳变、iOS 上闪屏,八成出在这组属性搭配上。
-
transition必须限定为transform和box-shadow,写成all 0.3s会连width、padding一起过渡,导致 hit area 收缩 -
transform: scale()在 hover 里慎用——文字缩放后可能撑破按钮边界,移动端尤其明显 - 加
will-change: transform可提前触发 GPU 合成,但只在真正需要高性能动画时启用,滥用反而增加内存开销
移动端安全区与点击区域失效
iOS 键盘弹出时按钮消失、小屏点不中,往往不是样式没写对,而是忽略了物理交互约束。
立即学习“前端免费学习笔记(深入)”;
-
bottom值必须含env(safe-area-inset-bottom),例如bottom: calc(20px + env(safe-area-inset-bottom)) - 按钮最小尺寸按物理像素算:至少
48px × 48px,用padding控制,别设死width/height - 加
touch-action: manipulation防 iOS 300ms 延迟,同时确保<button>元素有aria-label,否则屏幕阅读器和键盘 Tab 都绕过它
transform 或漏写的 env()。



















