今天,我深入学习了 CSS 高级动画 的实现技巧,并动手写了一个超可爱的动画小球项目!两个白色小球 👯♀️ 在屏幕上互动:左边的小球眨眼 😊,右边的小球则会"亲吻" 💋,整个画面温馨又充满童趣。这不仅是一次代码练习,更是一场 CSS 动画的艺术创作!
🧱 项目结构:简洁而优雅
html文件配合 css文件,我们实现了完整的动画界面。这体现了 "结构与样式分离" 的前端最佳实践。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS Animation</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="container">
<!-- 女主 -->
<div class="ball" id="l-ball">
<div class="face face-l">
<div class="eye eye-l"></div>
<div class="eye eye-r"></div>
<div class="mouth"></div>
</div>
</div>
<!-- 男主 -->
<div class="ball" id="r-ball">
<div class="face face-r">
<div class="eye eye-l eye-r-p"></div>
<div class="eye eye-r eye-r-p"></div>
<div class="mouth mouth-r"></div>
<div class="kiss-m">
<div class="kiss"></div>
<div class="kiss"></div>
</div>
</div>
</div>
</div>
</body>
</html>
css
* {
margin: 0;
padding: 0;
}
body {
background-color: rgb(192, 237, 255);
}
.container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 238px;
/* background-color: white; */
}
.ball {
background-color: white;
border: 8px solid;
width: 100px;
height: 100px;
border-radius: 50%;
display: inline-block;
position: relative;
}
.face {
width: 70px;
height: 30px;
position: absolute;
right: 0;
top: 30px;
}
/* 伪元素选择器
css 声明,像html一样来用,不需要在html里面声明
一定要有content属性 忍者 */
/* 元素内容开始之前 */
.face::after,
.face::before {
content: "";
position: absolute;
width: 18px;
height: 8px;
background-color:pink;
top: 20px;
border-radius: 50%;
}
.face::before {
right: -8px;
}
/* 元素内容结束之后 */
.face::after {
left: -5px;
}
.eye {
width: 15px;
height: 14px;
border-radius: 50%;
border-bottom: 5px solid;/* 仅保留底部边框形成弧线造型 */
position: absolute;
}
.eye-l {
left: 10px;
}
.eye-r {
right: 5px;
}
.eye-r-p {
border-top: 5px solid;
border-bottom: 0px solid;
}
.mouth {
width: 30px;
height: 14px;
border-radius: 50%;
border-bottom: 5px solid;
position: absolute;
bottom: -5px;
left: 0;
right: 0;
transform: translate(3px);
margin: auto;
/*平分左右的margin*/
}
/* 动画 */
#l-ball {
animation: close 4s ease infinite;
position: relative;
z-index: 100;
}
@keyframes close {
0% {
transform: translate(0);
}
20% {
transform: translate(20px);
}
35% {
transform: translate(20px);
}
55% {
transform: translate(0px);
}
100% {
transform: translate(0px);
}
}
.face-l {
animation: face 4s ease infinite;
}
@keyframes face {
0% {
transform: translate(0) rotate(0);
}
10% {
transform: translate(0) rotate(0);
}
20% {
transform: translate(5px) rotate(-2deg);
}
28% {
transform: translate(0) rotate(0);
}
35% {
transform: translate(5px) rotate(-2deg);
}
50% {
transform: translate(0) rotate(0);
}
100% {
transform: translate(0) rotate(0);
}
}
#r-ball {
animation: kiss 4s ease infinite;
}
@keyframes kiss {
40% {
transform: translate(0);
}
50% {
transform: translate(30px) rotate(20deg);
}
60% {
transform: translate(-33px);
}
67% {
transform: translate(-33px);
}
77% {
transform: translate(0px);
}
}
.mouth-r {
animation: mouth-m 4s ease infinite;
}
.kiss-m {
position: absolute;
left: 20px;
top: 22px;
opacity: 0;
animation: kiss-m 4s ease infinite;
}
.kiss {
width: 13px;
height: 10px;
background-color: white;
border-left: 5px solid;
border-radius: 50%;
}
@keyframes kiss-m {
0% {
opacity: 0;
}
55% {
opacity: 0;
}
66% {
opacity: 1;
}
66.1% {
opacity: 0;
}
}
@keyframes mouth-m {
0% {
opacity: 1;
}
54.9% {
opacity: 1;
}
55% {
opacity: 0;
}
66% {
opacity: 0;
}
66.1% {
opacity: 1;
}
}
.face-r {
left: 0;
top: 37px;
}
🎭 面向对象的 CSS:.face 基类与多态
在 readme.md 中提到:"面向对象的 css .face 基类 .face-l 多态"。这正是本项目的核心设计思想!
.face是一个通用基类,定义了脸部的基本位置和尺寸。.face-l和.face-r则是它的"子类",分别应用不同的动画(face动画 vs 默认静止),实现了 多态行为 ------ 同一个"脸"的结构,在不同球上表现不同动作。
css
.face { /* 基类:定义共性 */ }
.face-l { animation: face 4s ease infinite; } /* 左脸:眨眼动画 */
.face-r { /* 右脸:配合亲吻动作 */ }
这种写法让代码高内聚、低耦合,便于维护和扩展 👍。
✨ 关键动画解析
1️⃣ 左球:眨眼动画 👀
通过移动 .face-l 并轻微旋转,模拟"眨眼"效果:
css
@keyframes face {
20%, 35% {
transform: translate(5px) rotate(-2deg);
}
}
配合眼睛(.eye)的弧形边框设计,眨眼显得自然又灵动。
2️⃣ 右球:亲吻动画 💋
这是最精彩的部分!右球(#r-ball)执行 kiss 动画:
css
@keyframes kiss {
50% { transform: translate(30px) rotate(20deg); }
60% { transform: translate(-33px); } /* 快速靠近左球 */
}
同时,嘴巴(.mouth-r)在关键时刻隐藏,一个粉色"亲吻印记"(.kiss-m)短暂出现:
css
@keyframes kiss-m {
66% { opacity: 1; } /* 一闪而过的 kiss 💋 */
}
💖 这个设计巧妙利用了
opacity和精确的时间控制,让"亲吻"瞬间既浪漫又不突兀!
🎯 技术亮点总结
| 技术点 | 说明 |
|---|---|
| 水平垂直居中 | 使用 .container { position: absolute; top/left: 50%; transform: translate(-50%, -50%) },经典且兼容性好 ✅ |
| 伪元素绘图 | 用 ::before / ::after 画脸颊,无需额外 HTML 元素,轻量高效 🧼 |
| 边框绘图技巧 | 眼睛和嘴巴仅用 border-bottom + border-radius 实现弧线,极简主义美学 🎨 |
| 动画时间协调 | 所有动画统一 4s ease infinite,确保左右球动作同步,节奏和谐 ⏱️ |
🌈 学习感悟
通过这个小项目,我深刻体会到:
CSS 不只是样式,更是表现力和创造力的工具。
从面向对象的结构设计,到动画关键帧的精细调控,每一步都让我对 CSS 的能力有了新的认识。原来,用几行代码,就能让静态页面"活"起来,传递情感与故事 ❤️。
🔮 下一步计划
- 添加更多表情(比如害羞 blush、开心 smile)
- 响应用户交互(点击触发动画)
- 尝试用 CSS Houdini 实现更复杂的自定义动画
继续加油!CSS 动画的世界,远比想象中更精彩 🚀🌈