六、完整代码与效果演示
下面是完整的HTML + CSS代码,将以上所有部分整合在一起。你可以直接复制到一个 .html 文件中,在浏览器中打开预览。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>徘徊的果冻怪兽 - 纯CSS动画</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: #f0f4ff;
font-family: "Microsoft YaHei", sans-serif;
}
/* ===== 舞台 ===== */
.scene {
width: 440px;
height: 340px;
position: relative;
background: linear-gradient(160deg, #ffe4d6, #ffc8b0, #ffb3a0);
border-radius: 40px;
overflow: hidden;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.12);
/* 地面装饰线 */
}
.scene::after {
content: '';
position: absolute;
bottom: 38px;
left: 10%;
width: 80%;
height: 3px;
background: rgba(0,0,0,0.06);
border-radius: 50%;
filter: blur(2px);
}
/* ===== 怪兽主体 ===== */
.monster {
position: absolute;
bottom: 50px;
left: 50%;
width: 130px;
height: 150px;
margin-left: -65px;
background: radial-gradient(circle at 38% 28%, #f9b8d4, #a78bfa, #7c3aed);
border-radius: 50% 50% 45% 45% / 60% 60% 40% 40%;
box-shadow:
inset 0 -20px 50px rgba(255, 255, 255, 0.35),
inset 0 18px 40px rgba(0, 0, 0, 0.08),
0 18px 40px rgba(0, 0, 0, 0.18);
animation:
wander 4.5s ease-in-out infinite,
jelly 1.4s ease-in-out infinite;
z-index: 2;
}
/* ===== 触角 ===== */
.horn {
position: absolute;
width: 20px;
height: 20px;
background: #8b5cf6;
border-radius: 50% 50% 30% 30%;
top: -14px;
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
}
.left-horn {
left: 32px;
transform: rotate(-22deg);
animation: hornBobLeft 1.4s ease-in-out infinite;
}
.right-horn {
right: 32px;
transform: rotate(22deg);
animation: hornBobRight 1.4s ease-in-out infinite;
}
@keyframes hornBobLeft {
0%, 100% { transform: rotate(-22deg) translateY(0); }
50% { transform: rotate(-28deg) translateY(-8px); }
}
@keyframes hornBobRight {
0%, 100% { transform: rotate(22deg) translateY(0); }
50% { transform: rotate(28deg) translateY(-8px); }
}
/* ===== 眼睛 ===== */
.eye {
position: absolute;
width: 36px;
height: 40px;
background: #ffffff;
border-radius: 50%;
top: 42px;
box-shadow: 0 4px 16px rgba(0,0,0,0.08);
z-index: 3;
}
.left-eye {
left: 26px;
}
.right-eye {
right: 26px;
}
/* 瞳孔 */
.pupil {
position: absolute;
bottom: 6px;
left: 50%;
width: 16px;
height: 18px;
margin-left: -8px;
background: #1e1e2f;
border-radius: 50%;
animation: pupilMove 4.5s ease-in-out infinite;
}
@keyframes pupilMove {
0% { transform: translateX(0); }
25% { transform: translateX(5px); }
50% { transform: translateX(0); }
75% { transform: translateX(-5px); }
100% { transform: translateX(0); }
}
/* 眼睛高光(小亮点) */
.eye::after {
content: '';
position: absolute;
top: 6px;
right: 6px;
width: 10px;
height: 10px;
background: rgba(255,255,255,0.9);
border-radius: 50%;
filter: blur(1px);
}
/* ===== 嘴巴 ===== */
.mouth {
position: absolute;
bottom: 36px;
left: 50%;
width: 44px;
height: 18px;
margin-left: -22px;
border-bottom: 4px solid #5b21b6;
border-radius: 0 0 22px 22px;
animation: mouthChange 1.4s ease-in-out infinite;
z-index: 3;
}
@keyframes mouthChange {
0%, 100% {
border-bottom-width: 4px;
border-radius: 0 0 22px 22px;
}
50% {
border-bottom-width: 6px;
border-radius: 0 0 28px 28px;
}
}
/* ===== 腮红 ===== */
.blush {
position: absolute;
width: 26px;
height: 14px;
background: rgba(255, 130, 130, 0.35);
border-radius: 50%;
top: 74px;
z-index: 1;
filter: blur(3px);
}
.left-blush {
left: 10px;
}
.right-blush {
right: 10px;
}
/* ===== 关键帧动画 ===== */
/* 徘徊移动 */
@keyframes wander {
0% { transform: translateX(0px); }
20% { transform: translateX(70px); }
40% { transform: translateX(0px); }
60% { transform: translateX(-70px); }
80% { transform: translateX(0px); }
100% { transform: translateX(0px); }
}
/* 果冻弹性 */
@keyframes jelly {
0% {
transform: scale(1, 1) translateY(0);
border-radius: 50% 50% 45% 45% / 60% 60% 40% 40%;
}
15% {
transform: scale(0.88, 1.12) translateY(-10px);
border-radius: 55% 55% 40% 40% / 50% 50% 50% 50%;
}
30% {
transform: scale(1.06, 0.94) translateY(5px);
border-radius: 47% 47% 49% 49% / 62% 62% 38% 38%;
}
45% {
transform: scale(0.94, 1.06) translateY(-5px);
border-radius: 53% 53% 42% 42% / 55% 55% 45% 45%;
}
60% {
transform: scale(1.03, 0.97) translateY(2px);
border-radius: 49% 49% 46% 46% / 59% 59% 41% 41%;
}
80% {
transform: scale(1, 1) translateY(0);
border-radius: 50% 50% 45% 45% / 60% 60% 40% 40%;
}
100% {
transform: scale(1, 1) translateY(0);
border-radius: 50% 50% 45% 45% / 60% 60% 40% 40%;
}
}
/* ===== 地面阴影(增强立体感) ===== */
.shadow {
position: absolute;
bottom: 38px;
left: 50%;
width: 80px;
height: 14px;
margin-left: -40px;
background: rgba(0, 0, 0, 0.10);
border-radius: 50%;
filter: blur(6px);
animation: shadowScale 4.5s ease-in-out infinite;
z-index: 1;
}
@keyframes shadowScale {
0% { transform: scaleX(1); opacity: 0.6; }
25% { transform: scaleX(1.3); opacity: 0.3; }
50% { transform: scaleX(1); opacity: 0.6; }
75% { transform: scaleX(0.7); opacity: 0.8; }
100% { transform: scaleX(1); opacity: 0.6; }
}
</style>
</head>
<body>
<div class="scene">
<div class="monster">
<!-- 触角 -->
<div class="horn left-horn"></div>
<div class="horn right-horn"></div>
<!-- 左眼 -->
<div class="eye left-eye">
<div class="pupil"></div>
</div>
<!-- 右眼 -->
<div class="eye right-eye">
<div class="pupil"></div>
</div>
<!-- 嘴巴 -->
<div class="mouth"></div>
<!-- 腮红 -->
<div class="blush left-blush"></div>
<div class="blush right-blush"></div>
</div>
<!-- 动态阴影 -->
<div class="shadow"></div>
</div>
</body>
</html>效果说明: 怪兽在暖色渐变舞台上左右徘徊,身体持续进行挤压与拉伸的果冻弹性动画,瞳孔左右摆动,触角轻微晃动,嘴巴弧度也有微小变化。地面阴影同步缩放,增强了空间立体感。所有动画纯CSS驱动,无需任何JavaScript。
七、参数调优与扩展思路
你可以通过调整几个关键参数来改变怪兽的行为和外观:
| 参数 | 位置 | 效果 |
|---|---|---|
animation-duration(wander) | .monster 的 animation 属性 | 调整徘徊速度,数值越大移动越慢 |
animation-duration(jelly) | .monster 的 animation 属性 | 调整果冻弹动的频率,数值越小弹得越快 |
translateX 幅度 | @keyframes wander 中 | 改变徘徊的范围,数值越大走得越远 |
scale 值 | @keyframes jelly 中 | 调整挤压拉伸的强度,越偏离1.0形变越剧烈 |
background 颜色值 | .monster 的 background | 改变怪兽的肤色,可以换成绿色、蓝色等 |
扩展思路:
- 多只怪兽:复制多份
.monster,修改动画延迟(animation-delay),让它们在不同时间徘徊,形成群落效果。 - 互动反馈:配合
:hover或:target伪类,当鼠标悬停时改变动画状态(例如暂停或加快)。 - 表情切换:通过添加不同的类名(如
.happy、.sad),切换嘴巴和眼睛的样式,实现多表情怪兽。 - 果冻拖尾:使用
filter: blur()和opacity制作残影效果,让果冻感更强烈。 - 响应式缩放:使用
vw或clamp()单位,让怪兽在不同屏幕尺寸下自动适配大小。
八、常见问题与注意事项
- 动画卡顿:如果动画出现卡顿,请检查是否在动画属性中使用了
left、top等会触发重排的属性。建议只使用transform和opacity,它们在合成层上运行,性能最优。 - 浏览器兼容性:本文使用的
@keyframes、transform、border-radius等特性在现代浏览器中均有良好支持。如需兼容旧浏览器,请添加-webkit-前缀。 - 阴影重叠:注意
z-index的层级关系,确保触角在身体上方,眼睛在嘴巴上方,阴影在身体下方。 - 果冻形状:
border-radius的分数形式(如50% 50% 45% 45% / 60% 60% 40% 40%)分别控制水平半径和垂直半径,多尝试不同的比值可以塑造出独特的身体轮廓。
九、总结
通过本文的实践,我们仅用纯CSS就实现了一只可爱的“徘徊的果冻怪兽”。整个过程涵盖了:
- 使用
border-radius塑造不规则有机形态 - 通过
radial-gradient模拟光照与体积感 - 利用
@keyframes定义复合动画(位移 + 弹性形变) - 通过多元素协作营造生动的角色表情与动态细节
- 使用动态阴影增强场景的空间真实感
CSS动画的魅力在于,只要发挥想象力,即使不用图片和脚本,也能创造出有生命力的角色。希望你可以在本文的基础上,设计出属于你自己的怪兽家族。如果你有更多创意玩法,欢迎在实践中不断探索和分享。
* 本文所有代码均已在 Chrome 116、Edge 116、Firefox 117 中测试通过。