在网页界面中,卡片是最常见的容器形态之一。为了让卡片具备更生动的视觉层次,很多场景需要阴影不是固定不变的,而是随着时间产生缩放、位移或颜色深浅的变化。通过CSS的animation属性配合box-shadow,可以直接用纯样式实现这种动态阴影,不需要任何JavaScript参与。

一、box-shadow基础与动画可行性
box-shadow用来在元素框外或内绘制阴影,标准写法为水平偏移、垂直偏移、模糊半径、扩散半径和颜色。比如box-shadow: 0 4px 10px rgba(0,0,0,0.2)表示向下偏移4像素、模糊10像素的半透明黑影。由于box-shadow本身是支持渐变插值的可动画属性,只要关键帧之间参数数量与顺序一致,浏览器就能自动计算中间状态。
过去开发者习惯用transition在hover时切换阴影,但transition必须有状态变化触发。animation则允许页面加载后就自主循环播放,例如让卡片像呼吸一样周期性改变阴影深浅,这种效果在后台概览卡、活动入口卡上很常见。理解这一点,是写出稳定动画的前提。
二、使用keyframes定义阴影变化
实现动态阴影的第一步是在style中声明一个keyframes,把阴影在不同时间点的形态列出来。下面示例让卡片阴影从浅到深再回到浅,形成循环呼吸:
@keyframes shadowPulse {
0% {
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
50% {
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.25);
}
100% {
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
}
.card {
width: 240px;
height: 160px;
background: #fff;
border-radius: 8px;
animation: shadowPulse 3s ease-in-out infinite;
}
上面代码中,关键帧的box-shadow都保持相同的参数结构,仅改变偏移、模糊和透明度,因此浏览器可以平滑插值。ease-in-out让节奏更自然,infinite使动画不断循环。如果希望只播放一次,把infinite改为forwards并调整填充模式即可。
需要注意的是,若某一帧写成box-shadow: inset 0 0 5px #000而另一帧无inset,结构不一致会导致动画跳变。保持内外阴影类型统一,是避免渲染异常的关键。
三、结合位移与颜色做更丰富的效果
除了深浅变化,还可以让卡片在阴影拉长时轻微上移,强化浮起感。通过同时动画transform与box-shadow,视觉反馈更明显:
@keyframes floatShadow {
0% {
transform: translateY(0);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
50% {
transform: translateY(-6px);
box-shadow: 0 14px 24px rgba(0, 0, 0, 0.3);
}
100% {
transform: translateY(0);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}
}
.card-float {
padding: 16px;
background: #fafafa;
animation: floatShadow 4s ease-in-out infinite;
}
这段样式把位移和阴影绑定在同一个时间轴里,用户会感觉卡片被托起又落下。相比单改阴影,组合变换更抓眼球,但要注意translateY值不宜过大,否则在密集布局中会遮挡邻块。
在色彩上,也可以将阴影色从黑灰切换为品牌色,比如电商卡用橙色影调。只需把rgba中的色值替换,并确认各帧格式相同,就能实现彩色呼吸阴影,且不会增加DOM节点。
四、性能与兼容注意事项
box-shadow动画属于绘制密集型操作,在低端设备可能掉帧。建议对动画元素加will-change: box-shadow, transform提示浏览器单独分层,但不要在过多元素上滥用,否则内存上升。另外,模糊半径越大越耗性能,卡片列表场景可将模糊控制在20px内。
兼容性方面,现代浏览器均支持box-shadow与animation,但在旧版IE上完全无效。如果必须照顾老环境,可用transition配合JS轮播class降级处理。下表列出常用配置建议:
| 场景 | 动画时长 | 模糊半径 | 循环方式 |
|---|---|---|---|
| 后台数据卡 | 3s | 6-18px | infinite |
| 营销弹窗卡 | 2.4s | 10-24px | infinite alternate |
| 一次性引导卡 | 1.8s | 8-16px | forwards |
通过合理选择时长与缓动,既能保证流畅,也能突出视觉重点。当卡片数量较多时,可考虑仅对首屏或重要卡开启动画,其余用静态阴影。
五、完整页面示例
下面给出一个最小可运行页面,展示两张卡片分别使用呼吸阴影与浮动阴影:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>CSS动画卡片阴影</title>
<style>
body { display: flex; gap: 30px; padding: 40px; background: #eee; }
.card {
width: 200px; height: 120px; background: #fff;
border-radius: 10px; display: flex;
align-items: center; justify-content: center;
}
@keyframes shadowPulse {
0% { box-shadow: 0 2px 6px rgba(0,0,0,0.1); }
50% { box-shadow: 0 10px 20px rgba(0,0,0,0.25); }
100% { box-shadow: 0 2px 6px rgba(0,0,0,0.1); }
}
@keyframes floatShadow {
0% { transform: translateY(0); box-shadow: 0 4px 8px rgba(0,0,0,0.15); }
50% { transform: translateY(-6px); box-shadow: 0 14px 24px rgba(0,0,0,0.3); }
100% { transform: translateY(0); box-shadow: 0 4px 8px rgba(0,0,0,0.15); }
}
.pulse { animation: shadowPulse 3s ease-in-out infinite; }
.float { animation: floatShadow 4s ease-in-out infinite; }
</style>
</head>
<body>
<div class="card pulse">呼吸阴影卡片</div>
<div class="card float">浮动阴影卡片</div>
</body>
</html>
将以上代码保存为html文件用浏览器打开,即可看到纯CSS驱动的阴影动画。实际项目中,把keyframes抽离到公共样式表,再通过不同class组合,就能在任意卡片上复用动态阴影能力。
总体来看,用CSS animation结合box-shadow实现卡片阴影变化,写法直观、运行轻量,是提升界面质感的有效手段。只要遵循参数结构一致、控制模糊规模、按需开启分层,就能在多数业务中平稳落地。
CSS_animationbox-shadowcss_card_shadow修改时间:2026-08-07 11:18:38