🌟 CSS考题:双球热吻动画の十二重奥义解密

138 阅读8分钟

🌟 CSS魔法学院:双球热吻动画の十二重奥义解密

✨ 前言
当两个圆滚滚的CSS球体在屏幕上眉目传情,你是否好奇这数字罗曼史背后的代码奥秘?今天我们将化身CSS魔法师,用纯代码演绎一场跨次元的恋爱大戏!


🎭 先睹为快:最终效果全景图

7186bee27e64429e92eb1e6eb4987626~tplv-73owjymdk6-jj-mark-v1_0_0_0_0_5o6Y6YeR5oqA5pyv56S-5Yy6IEAg6L276K-t5ZGi5ZaD_q75.webp


🧙♂️ 咒语准备:HTML骨架速成术

1. Emmet语法闪电战

<!-- 终极召唤术:一键生成双球容器 -->
.container>#l-ball.ball+#r-ball.ball

咒语解析

  • > 表示父子关系,+ 表示兄弟关系
  • # 生成id,. 生成class
  • 最终召唤出:
<div class="container">
  <div id="l-ball" class="ball"></div>
  <div id="r-ball" class="ball"></div>
</div>

2.Emmet语法速查表

HTML常用语法
语法效果
div<div></div>
div.container<div class="container"></div>
div#main<div id="main"></div>
ul>li*3生成3个列表项
a[href="#" target="_blank"]带属性的链接
p{文本内容}<p>文本内容</p>
h1~p同级元素:<h1></h1><p></p>
(div>p)+span分组与嵌套
CSS常用语法
语法效果
w100width: 100px;
m20margin: 20px;
dfdisplay: flex;
jc-cjustify-content: center;
c#fffcolor: #fff;
fz16font-size: 16px;
进阶技巧
  • 编号li.item$*3item1, item2, item3
  • 文本a{点击我}<a>点击我</a>
  • HTML模板:输入 ! 后按 Tab 生成完整HTML5骨架
使用方法

在编辑器(如VS Code)中输入缩写,按 Tab 键展开。例如:

  1. 输入 nav>ul>li*4>a,按 Tab → 生成导航栏
  2. 输入 d:f+jcc+aic,按 Tab → 生成flex居中样式

3. 表情元素解剖学

<!-- 左球的五官构造 -->
<div class='face face-l'>
  <div class='eye eye-l'></div>  <!-- 左眼 -->
  <div class='eye eye-r'></div>  <!-- 右眼 -->
  <div class='mouth'></div>      <!-- 嘴巴 -->
</div>
<div class='eye eye-l'></div>  <!-- 左眼 -->
<div class='eye eye-r'></div>  <!-- 右眼 -->

这两个元素都属于以下类:

  1. 公共类

    • eye:两个元素都具有这个类,通常用于定义眼睛的通用样式(如大小、形状、颜色等)。
  2. 差异化类

    • eye-l:仅左眼元素具有,用于定义左眼的特殊样式(如位置偏移)。
    • eye-r:仅右眼元素具有,用于定义右眼的特殊样式(如位置偏移)。

💡 设计哲学:每个表情器官都是独立组件,像搭积木般自由组合


🎨 CSS绘世录:从圆球定位到表情

1. 创世之圆:球体诞生

实现容器的居中

container{
  position: absolute;
  top: 50%;
  left: 50%; //将该元素的左上角放在网页中间
  width: 238px;
  height: 238px;//将该元素设为边长为238像素点的正方形
  background-color: pink;//给该块级元素设置颜色,方便调试,前端调试大法
  transform: translate(-50%, -50%);}//将元素从原始位置向左移动自身宽度的 50%,向上移动自身高度的 50%

在 CSS 中,position: absolute; 是一种定位方式,用于将元素从正常文档流中移除(即其他的元素可以占据他的位置,在container上放置,所以为容器),并相对于其最近的已定位祖先元素(即设置了 position: relativeabsolutefixed 或 sticky 的祖先)进行定位。如果没有已定位的祖先元素,则相对于浏览器窗口(即初始包含块)定位。

image.png

开始正式放置球的位置

.ball {
    width: 100px;
    height: 100px;
    border: 8px solid black;
    border-radius: 50%;
    /* 把圆角变成50% */
    display: inline-block;
    /* 修改元素的显示类型,变成行内块元素 incline-block 位于行内元素和块级元素之间*/
    background-color: white;
    vertical-align: top;
    position: relative;
    /* 相对定位:里面的子元素相对它定位 */
    /* top: 50%; left: 50%;*/ 
}

在 CSS 中,position: relative(相对定位)是一种重要的定位方式,其核心作用是在不脱离文档流的前提下,微调元素的位置,或为子元素提供定位基准。以下是详细解析:

  • 不脱离文档流
    元素仍占据原文档流中的空间,不会影响其他元素的布局。
  • 相对于原始位置定位
    通过 toprightbottomleft 属性,元素可相对于其原始位置进行偏移。
  • 层级提升
    相对定位的元素会创建一个新的层叠上下文(stacking context),可通过 z-index 控制与其他元素的覆盖关系。

在 CSS 中,display: inline-block; 是一种混合显示模式,它结合了 行内元素 和 块级元素 的特性,使元素能够在保持块级元素特性的同时,像行内元素一样水平排列。

如此两个小球的身体部分便做好了

image.png

2. 表情雕刻术:边框魔法

先和之前一样,确定脸部的位置

.face{
           width: 70px;
            height: 30px;
            position: absolute; //相当于一个脸部的容器,眼睛和嘴巴将会占据脸部元素的位置
            right: 0;
            top: 30px;//将脸部元素相比于父级元素进行移动
            border-top-right-radius:15px;//设置元素右上角的圆角
            background-color: green; //设置背景颜色,便于观察与调试
        }

image.png

.eye {
  border-bottom: 5px solid; /* 睁眼咒 */
  &.eye-r-p {
    border-top: 5px solid;  /* 闭眼咒 */
  }
}

效果对比

状态代码片段视觉呈现
睁眼border-bottom: 5px solid👁️
闭眼border-top: 5px solid-

image.png


🕺 动画交响曲:关键帧舞蹈编排

1. 时间领主の秘籍

@keyframes kiss {
  50% {
    transform: translate(30px) rotate(20deg); /* 冲锋陷阵 */
  }
  60% {
    transform: translate(-33px); /* 弹性后撤 */
  }
}

2. 精准时序控制表

时间点左球动作右球动作交互事件
50%复位前冲30px发起攻势
55.1%-显示唇印亲密接触
60%-回弹欲拒还迎

🧭 定位迷踪:四大空间法则

1. 绝对定位奥义

.container {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%); /* 空间扭曲术 */
}

2. 层级战争の生存法则

#l-ball { z-index: 50; } /* C位特权 */
#r-ball { z-index: 40; } /* 优雅退让 */

💥 黄金法则:数值越大离用户越近,像俄罗斯套娃般层层叠加 这段 CSS 代码是在设置两个元素的层叠顺序,也就是它们在 Z 轴方向上的显示优先级。z-index的值越大,元素就越 "靠近" 用户,会覆盖在值较小的元素上方。


🚀 性能优化圣典

1. GPU加速咒

.ball {
  transform: translateZ(0); /* 唤醒显卡之力 */
  will-change: transform;   /* 预加载提示 */
}

2. 动画属性三戒

  1. 优先使用transformopacity
  2. 避免box-shadow等昂贵属性
  3. 精简关键帧数量

🧪 完整咒语手册

完整代码示例

HTML

    xml
     体验AI代码助手
     代码解读
    复制代码
    <!DOCTYPE html>
    <html lang="en">

    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
     
    </head>

    <body>
      <div class='container'>
        <div id='l-ball' class='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 id='r-ball' class='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**:
```css
     <style>
        body {
          background-color: #78e08f;
          margin: 0;
        }

        .container {
          margin: auto;
          position: absolute;
          top: 50%;
          left: 50%;
          -webkit-transform: translate(-50%, -50%);
          -ms-transform: translate(-50%, -50%);
          transform: translate(-50%, -50%);
          width: 238px;
        }

        .face {
          width: 70px;
          height: 30px;
          position: absolute;
          right: 0;
          top: 30px;
          border-top-right-radius: 15px;
        }

        #r-ball {
          animation: kiss 4s ease infinite;
          background-color: white;
        }

        @keyframes kiss {
          40% {
            transform: translate(0px);
          }

          50% {
            transform: translate(30px) rotate(20deg);
          }

          60% {
            transform: translate(-33px);
          }

          67% {
            transform: translate(-33px);
          }

          77% {
            transform: translate(0px);
          }
        }

        .kiss {
          width: 13px;
          height: 10px;
          background-color: white;
          border-radius: 50%;
          border-left: 5px solid;
        }

        .kiss-m {
          position: absolute;
          left: 20px;
          top: 22px;
          opacity: 0;
          animation: kiss-m 4s ease infinite;
        }

        @keyframes kiss-m {
          0% {
            opacity: 0;
          }

          55% {
            opacity: 0;
          }

          55.1% {
            opacity: 1;
          }

          66% {
            opacity: 1;
          }

          66.1% {
            opacity: 0;
          }
        }

        .mouth-r {
          animation: mouth-m 4s ease infinite;
        }

        @keyframes mouth-m {
          0% {
            opacity: 1;
          }

          54.9% {
            opacity: 1;
          }

          55% {
            opacity: 0;
          }

          66% {
            opacity: 0;
          }

          66.1% {
            opacity: 1;
          }
        }

        .face:after {
          position: absolute;
          content: "";
          width: 18px;
          height: 8px;
          background-color: #badc58;
          left: -5px;
          top: 20px;
          border-radius: 50%;
        }

        .face:before {
          position: absolute;
          content: "";
          width: 18px;
          height: 8px;
          background-color: #badc58;
          right: -8px;
          top: 20px;
          border-radius: 50%;
          z-index: -1;
        }

        .face-r {
          left: 0;
          top: 37px;
        }

        .face-r:after {
          width: 10px;
          height: 10px;
          left: 5px;
        }

        .face-r:before {
          width: 10px;
          height: 10px;
          right: -4px;
        }

        .eye {
          width: 15px;
          height: 14px;
          border-radius: 50%;
          border-bottom: 5px solid;
          position: absolute;
        }

        .eye-r-p {
          border-top: 5px solid;
          border-bottom: 0px solid;
        }

        .eye-l {
          left: 10px;
        }

        .eye-r {
          right: 5px;
        }

        .mouth {
          width: 30px;
          height: 14px;
          border-radius: 50%;
          border-bottom: 5px solid;
          position: absolute;
          bottom: -5px;
          transform: translate(3px);
          left: 0;
          right: 0;
          margin: auto;
        }

        .ball {
          border: 8px solid;
          width: 100px;
          height: 100px;
          border-radius: 50%;
          display: inline-block;
          vertical-align: top;
          position: relative;
        }

        #r-ball {
          position: relative;
          z-index: 40;
          float: right;
        }


        #l-ball {
          animation: close 4s ease infinite;
          position: relative;
          z-index: 50;
          background-color: #fff;
        }

        .face-l {
          animation: face 4s ease infinite;
        }

        @keyframes close {
          0% {
            transform: translate(0)
          }

          20% {
            transform: translate(20px)
          }

          35% {
            transform: translate(20px)
          }

          55% {
            transform: translate(0px)
          }

          100% {
            transform: translate(0px)
          }
        }

        @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);
          }
        }
      </style>


🌌 星际拓展指南

1. 创意改造实验室

  • 添加心跳波纹:box-shadow扩散动画
  • 实现拖拽约会:结合JavaScript事件
  • 创建多皮肤系统:CSS变量魔法

2. 性能监测台

/* 调试模式 */
.debug {
  outline: 1px solid red;
  background: rgba(255,0,0,0.1);
}

🚀 结语
通过这场CSS的浪漫邂逅,我们见证了代码如何演绎生命律动。每个属性都是音符,每段动画都是乐章,当技术遇上创意,冰冷的代码也能绽放温暖的人性光辉。愿你手持这份魔法图鉴,在前端宇宙中书写更多动人篇章!