H5卡片“hover/touchstart阴影+升起”需双路径策略:鼠标用:hover,触控用touchstart加class;transition必须定义在基础状态,仅过渡box-shadow和transform,适配高DPI屏幕并避免父容器裁剪阴影。

在 H5 页面中,卡片的“hover 或 touchstart 时阴影 + 升起”效果不能靠单一 :hover 实现——因为移动端没有持续悬停,iOS Safari 和主流安卓浏览器对 :hover 的支持极弱,点一下就失效,甚至完全不触发。必须用“鼠标设备走 :hover,触控设备走 touchstart/active”的双路径策略,同时保证过渡自然、不跳变、不糊边。
必须在默认状态声明 transition
很多人把 transition 写在 .card:hover 里,结果移出时阴影“啪”地跳回。这是错误的。过渡行为必须定义在基础状态:
- .card { transition: box-shadow 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94), transform 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94); }
- 只过渡 box-shadow 和 transform,禁用 all —— 避免意外触发文字、边框等属性重绘
- 缓动函数推荐 cubic-bezier(0.25, 0.46, 0.45, 0.94),比 ease 更轻快,符合“弹性升起”直觉
hover 和 touchstart 要用不同但一致的触发逻辑
:hover 仅限鼠标设备;touchstart 是触控设备的可靠入口。两者最终都应作用于同一组样式变化:
- 鼠标设备:.card:hover { transform: translateY(-4px); box-shadow: 0 8px 20px rgba(0,0,0,0.12); }
- 触控设备:给卡片加 JS 监听 touchstart(或 pointerdown),动态添加 .card--lifted 类:
element.addEventListener('touchstart', () => element.classList.add('card--lifted'));
再写 CSS:
.card--lifted { transform: translateY(-4px); box-shadow: 0 8px 20px rgba(0,0,0,0.12); } - 为兼顾可访问性,也建议加上 :focus 和 :active 状态,例如 .card:focus, .card:active, .card--lifted
阴影参数要适配高 DPI 屏幕
在 iPhone Retina 或安卓旗舰机上,box-shadow 容易发灰、糊边或抖动。关键调整点:
- 所有数值用整数:8px、20px,避开 0.5px、1.2px
- 模糊半径不低于 8px(4px 在 Retina 下几乎不可见)
- 浅色背景用 rgba(0,0,0,0.12),深色背景改用 rgba(255,255,255,0.08)
- 避免 box-shadow 多层叠加(如内阴影+外阴影混用),否则过渡卡顿
父容器别裁剪阴影,否则效果消失
卡片升起后阴影向下延伸,若父容器设了 overflow: hidden,阴影会被直接切掉——这不是 bug,是渲染规则:
- 临时调试:给父容器加 border: 1px solid transparent,看清实际范围
- 稳妥做法:父容器加 padding-bottom: 20px(对应最大阴影垂直扩散距离)
- 若无法改父容器,卡片自身加 margin-bottom: 20px,确保投影区域落在可视区内
- Bootstrap 用户注意:卡片需包裹在 position-relative 容器中,否则 shadow 类可能被裁剪











