在这个数字时代,我们用代码表达情感,用样式表书写浪漫。今天,我将带你走进一段由CSS编织的恋爱故事——两个小球,在页面中央相遇、眨眼、微笑,最终献上一个甜蜜的吻。这不仅是一次技术实践,更是一封写给前端开发的情书。
🌟 故事背景:两个球的爱情故事
想象一下,页面中央有两个害羞的小球:
- 左边的球(
#l-ball)微微靠近,像是在说:“你好呀。” - 右边的球(
#r-ball)鼓起勇气,转身、前冲,献上一个飞吻 💋
而这一切,全部由纯 CSS 实现,没有一行 JavaScript。
🎬 第一幕:舞台搭建 —— 水平垂直居中
一切浪漫的开始,都需要一个完美的舞台。
css
编辑
.container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 238px;
}
📌 技巧解析:
top: 50%; left: 50%把容器移到视口中心transform: translate(-50%, -50%)让容器自身也居中(否则是左上角对齐)- 这是目前最通用、最可靠的居中方案
🎭 第二幕:角色登场 —— 画出两个可爱的球
css
编辑
.ball {
background-color: white;
border: 8px solid;
width: 100px;
height: 100px;
border-radius: 50%;
display: inline-block;
position: relative;
}
🎨 设计亮点:
border-radius: 50%变圆球display: inline-block让两个球并排position: relative为后续绝对定位的“脸”提供参考系
👀 第三幕:赋予灵魂 —— 用 .face 基类构建表情系统
我们采用 面向对象的CSS思想,定义一个“脸”的基类,再通过多态实现不同角色的表情。
✅ 基类 .face:所有脸的共性
css
编辑
.face {
width: 70px;
height: 30px;
position: absolute;
right: 0;
top: 30px;
}
✅ 多态实现:.face-l 与 .face-r
css
编辑
.face-l {
animation: face 4s ease infinite;
}
.face-r {
left: 0;
top: 37px;
}
🧠 设计哲学:
.face是“模板”,定义了脸的基本尺寸和位置逻辑.face-l和.face-r是“实例”,继承并扩展了.face的行为- 遵循 DRY(Don't Repeat Yourself)原则,避免重复代码
💘 第四幕:心动瞬间 —— 动画系统解析
1. 左球的“靠近”动画
css
编辑
#l-ball {
animation: close 4s ease infinite;
}
@keyframes close {
0%, 55%, 100% { transform: translate(0); }
20%, 35% { transform: translate(20px); }
}
👉 模拟“靠近 → 停顿 → 回退”的害羞动作
2. 右球的“亲吻”动画
css
编辑
#r-ball {
animation: kiss 4s ease infinite;
}
@keyframes kiss {
50% { transform: translate(30px) rotate(20deg); } /* 冲上去 */
60% { transform: translate(-33px); } /* 快速后退 */
77% { transform: translate(0); } /* 回到原位 */
}
🎯 关键点:z-index: -100 应该去掉!否则右球会“穿模”到左球后面。
💋 第五幕:飞吻特效 —— 用伪元素制造惊喜
我们用一个 .kiss-m 容器,配合 .kiss 元素,制造一个“飞吻”效果。
css
编辑
.kiss {
width: 13px;
height: 10px;
background-color: white;
border-left: 5px solid;
border-radius: 50%;
}
💡 视觉技巧:
border-left: 5px solid形成“心形”的一侧- 实际上是一个倾斜的椭圆,模拟“飞吻”的轨迹
动画控制:精准的时间轴
css
编辑
@keyframes kiss-m {
66% { opacity: 1; } /* 吻出现 */
66.1%{ opacity: 0; } /* 瞬间消失,避免重叠 */
}
⏰ 为什么用 66.1%?
为了避免与 mouth-m 动画在同一帧切换造成闪烁,微小的时间差让动画更流畅。
🧩 DRY 原则实践:避免重复代码
我们如何做到不重复?
| 技巧 | 应用场景 |
|---|---|
| 基类 + 多态 | .face 为基类,.face-l/.face-r 扩展 |
| 伪元素 | 用 ::before/::after 画装饰,无需额外HTML |
| 全局重置 | * { margin: 0; padding: 0; } 统一默认样式 |
| 语义化类名 | .eye, .mouth 明确职责 |
🌈 总结:CSS 不只是样式,更是叙事语言
通过这个案例,我们看到了:
- 技术层面:居中、动画、伪元素、面向对象CSS
- 设计层面:用代码讲一个动人的故事
- 哲学层面:DRY 原则如何让代码更优雅
CSS 的魅力,不仅在于它能让页面“好看”,更在于它能让页面“有情感”。
下次当你写 CSS 时,不妨问自己:
“这段代码,是在讲一个怎样的故事?”