在文章(juejin.cn/post/756728…)我们解析了 “小球亲吻” 动画的 HTML 骨架与样式后,接下来聚焦其 “亲吻” 动作的实现逻辑,这其中藏着不少 CSS 动画的 “秘密”。
我们先来看这段实现核心动效的 CSS 代码:
#l-ball {
animation: close 4s ease infinite;
position: relative;
z-index: 100;
}
@keyframes close {
0%{
transform: translate(0px);
}
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(5px)rotate(-2deg);
}
100%{
transform: translate(0)rotate(0);
}
}
#r-ball{
animation: kiss 4s ease infinite;
z-index: 10;
}
@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;
}
@keyframes mouth-m {
}
.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;
}
我们将 close 动画绑定到 #l-ball 元素:
#l-ball {
animation: close 4s ease infinite;
position: relative;
z-index: 100;
}
@keyframes close {
0%{
transform: translate(0px);
}
20%{
transform: translate(20px);
}
35%{
transform: translate(20px);
}
55%{
transform: translate(0px);
}
100%{
transform: translate(0px);
}
}
close:指定调用的动画名称,对应定义的@keyframes close关键帧规则,描述左侧小球的移动轨迹。4s:动画持续时长为 4 秒。ease:动画速度曲线为 “缓动”,呈现开始慢、中间快、结束慢的自然过渡效果。infinite:动画无限循环播放,小球动作持续往复。translate:属于 CSStransform属性的平移函数,可让元素沿 X、Y 或 Z 轴移动,且不影响其他元素布局,区别于margin移动。
关于 “为什么亲吻特效容器用 position: absolute,而其他元素不用” 的问题,我们可以这样理解:亲吻特效是临时显示的装饰性元素,类似 “气泡”,需要相对于右侧小球的脸部(.face-r)精准定位在嘴巴附近(left:20px; top:22px)。absolute 定位能使其脱离文档流,不受其他元素布局干扰,直接 “贴合” 在已定位的父元素(.face-r 通常设置了 position: relative 或 absolute)指定位置,确保特效与嘴巴位置严格对齐。
absolute 定位的核心作用是 “脱离原有布局,相对于父元素精准定位”。亲吻特效因需要这种 “悬浮式精准定位” 而采用该属性,其他元素则根据自身布局角色(如主体容器、内部结构承载等),选择了 relative 或默认定位等更适配的方式。
在 CSS 动画的世界里,不必执着于死记硬背每一种样式的尺寸、位置细节 —— 样式千变万化,创意作品更是层出不穷。很多时候,一个瞬间的灵感迸发,就能催生出令人眼前一亮的作品。当然,扎实的调试能力也必不可少,当你对效果不满意时,不妨打开 F12 开发者工具,在调试面板中灵活调整参数,将那些 “不合适” 的细节逐一打磨,让创意在实践中不断完善。
从 HTML 容器的层层嵌套,到 CSS 样式的细节雕琢,再到关键帧动画的协同配合,我们一步步拆解了 “小球亲吻” 动画的实现逻辑。左右小球的移动轨迹、脸部的微调动效、亲吻瞬间的特效与嘴巴隐藏的联动,看似简单的互动背后,是定位属性、动画参数与元素层级的精准把控。
其实,CSS 动画的魅力正在于此 —— 无需复杂代码,只需理清元素关系、设计合理的关键帧,就能让静态页面变得生动有趣。这个 “小球情侣” 的案例,也为我们后续设计类似互动动画提供了思路:从整体结构出发,聚焦细节动效,再通过参数对齐让各部分协同,就能让简单元素绽放出不一样的活力。