画对情侣兔, 祝大家中秋节有情人终将团圆

引言

时间像流水般匆匆而过, 一眨眼中秋节就要到了!! 既然如此那就让我用 CSS 画一对 相互依偎的情侣兔 吧!!! 借此祝福大家, 相信在月圆之夜, 有情人终将团圆, 共享美满幸福的时刻!! 在这个特殊的中秋节里, 让我们一同感受爱情的魅力 🐶🐶🐶🐶🐶

image

如图就是我们今天要绘制的 情侣兔, 下面将会针对图上几个难点(耳朵、眼睛、嘴巴、眉毛、腮红…)进行一个拆解, 至于完整的绘制代码可以查看这几个👇🏻链接

一、兔子耳朵

如图, 是 耳朵 部分的一个绘制过程

  • 最初是由嵌套的一组长方形组成
  • 通过设置圆角, 变成椭圆
  • 通过设置投影, 增加立体感
  • 最后通过 transform 进行一个旋转

image

  1. 基本框架: 其实就是一个 div 配合伪元素 ::after 组成嵌套长方形, 并且通过 flex 进行简单的布局, 并设置基本的宽高、背景色(包括外层的实色背景、内层的渐变背景)
<style>
  .ear {
    width: 160px;
    display: flex;
    justify-content: space-between;
    
    .ear-left,
    .ear-right {
      width: 40px;
      height: 150px;
      background-color: #fff;

      display: flex;
      align-items: center;
      justify-content: center;

      &::after {
        content: "";
        width: 50%;
        height: 50%;
        display: block;
        background: linear-gradient(#e5a9ab, #fcf8f7);
      }
    }
  }
</style>
<div class="ear">
  <div class="ear-left"></div>
  <div class="ear-right"></div>
</div>
  1. 设置圆角: 这里为每一组的内外两个长方形设置圆角, 这里需要补充一点 border-radius 实际上是可以设置八个值的, 具体的细节这里就不展开了, 而这边之所以这么写目的是为了让耳朵整体开起来更自然点
<style>
  .ear {
    ...
    .ear-left,
    .ear-right {
      ...
+     border-radius: 45% 45% 50% 50% / 45% 45% 50% 50%;

      &::after {
        ....
+       border-radius: 45% 45% 50% 50% / 45% 45% 50% 50%;
      }
    }
  }
</style>
  1. 设置投影: 这里通过 box-shadow 为每个矩形设置不一样的投影

<style>
  .ear {
    ....
    
    .ear-left,
    .ear-right {
      ...
+     box-shadow: inset 0 4px 4px 4px #ccc;
    }
+     .ear-left {
+       &::after {
+         box-shadow: inset -1px 2px 0 1px #cf7674;
+       }
+     }
+
+     .ear-right {
+       &::after {
+         box-shadow: inset 1px 2px 0 1px #cf7674;
+       }
+     }
+   }
</style>
  1. 旋转: 最后最后通过 transform 为两个耳朵进行一个小幅度的旋转
<style>
  .ear {
    ...
    
    .ear-left,
    .ear-right {
      ...
      &::after {
        ...

+       transform-origin: center center;
      }
    }
    .ear-left {
+     transform: rotate(-15deg);
      ...
    }

    .ear-right {
+     transform: rotate(15deg);
      ...
    }
  }
</style>
  1. 下面是本节, 也就是 两个耳朵 的一个完整的实现代码
<style>
  body {
    padding: 100px;
    background-color: #c9daf8;
  }

  .ear {
    width: 160px;
    display: flex;
    justify-content: space-between;
    
    .ear-left,
    .ear-right {
      width: 40px;
      height: 150px;
      background-color: #fff;

      display: flex;
      align-items: center;
      justify-content: center;

      border-radius: 45% 45% 50% 50% / 45% 45% 50% 50%;
      box-shadow: inset 0 4px 4px 4px #ccc;

      &::after {
        content: "";
        width: 50%;
        height: 50%;
        display: block;

        background: linear-gradient(#e5a9ab, #fcf8f7);
        border-radius: 45% 45% 50% 50% / 45% 45% 50% 50%;
        transform-origin: center center;
      }
    }
    .ear-left {
      transform: rotate(-15deg);

      &::after {
        box-shadow: inset -1px 2px 0 1px #cf7674;
      }
    }

    .ear-right {
      transform: rotate(15deg);

      &::after {
        box-shadow: inset 1px 2px 0 1px #cf7674;
      }
    }
  }
</style>
<div class="ear">
  <div class="ear-left"></div>
  <div class="ear-right"></div>
</div>

补充说明: 从最终的图可以发现, 兔子耳朵实际上底部是缺了一小段的, 这里其实是通过一个白色遮罩盖住了(如下图所示), 当然为了过渡显得自然点, 对于遮罩可以简单给个渐变或者投影

image

二、公兔眼睛

如图, 是 公兔眼睛 的一个绘制过程

  • 最初是由嵌套 3 个正方形 组成
  • 通过设置圆角, 变成椭圆
  • 通过 transform 进行一个旋转
  • 通过定位, 设置眼白的位置
  • 最后通过 box-shadow 给眼白设置一个阴影

image

  1. 基本结构: 通过一个 div 配合两个伪元素(::before::after)完成 3 个正方形 的实现, 并设置基本的宽高、背景色
<style>
  .male {
    width: 160px;
    display: flex;
    justify-content: space-between;

    .eye-left,
    .eye-right {
      width: 20px;
      height: 25px;
      background-color: #ba300e;

      &::before,
      &::after {
        content: "";
        display: block;
        background-color: #fff;
      }

      &::before {
        width: 8px;
        height: 8px;
      }

      &::after {
        width: 3px;
        height: 3px;
      }
    }
  }
</style>

<div class="male">
  <div class="eye-left"></div>
  <div class="eye-right"></div>
</div>
  1. 设置圆角: 同耳朵那节, 通过 border-radius 为眼球设置不同的圆角, 实现鹅软石般的大眼睛
<style>
  .male {
    ...

    .eye-left,
    .eye-right {
      ...
+     border-radius: 50% 50% 60% 60% / 50% 50% 60% 60%;

      &::before,
      &::after {
+       border-radius: 50%;
        background-color: #fff;
      }
      ...
    }
  }
</style>
  1. 旋转: 通过 transform 将眼睛进行小角度的旋转
<style>
  .male {
    ...
    .eye-left,
    .eye-right {
      ....
    }

+   .eye-left {
+     transform: rotate(-45deg);
+   }
+
+   .eye-right {
+     transform: rotate(45deg);
+   }
  }
</style>
  1. 眼白定位: 使用 position 将眼白定位到正确的位置
<style>
  .male {
    ...

    .eye-left,
    .eye-right {
      ...
+     position: relative;
      ...

      &::before,
      &::after {
        ...
+       position: absolute;
        ...
      }
      ...
    }

    .eye-left {
      ...
+     &::before {
+       top: 6px;
+       left: 10px;
+     }
+
+     &::after {
+       top: 5px;
+       left: 3px;
+     }
    }

    .eye-right {
      transform: rotate(45deg);

+     &::before {
+       top: 5px;
+       right: 10px;
+     }

+     &::after {
+       top: 2px;
+       right: 5px;
+     }
    }
  }
</style>
  1. 设置阴影: 这里通过 box-shadow 为眼白设置一个白色的阴影, 让整体看起来不显得生硬
<style>
  .male {
    ...
    .eye-left,
    .eye-right {
      ...
      &::before {
        ...
+       box-shadow: 0 0 4px #fff;
      }

      &::after {
        ...
+       box-shadow: 0 0 2px #fff;
      }
    }
    ...
  }
</style>
  1. 下面是本节, 也就是 公兔的两个眼睛 的一个完整的实现代码
<style>
  body {
    padding: 100px;
    background-color: #c9daf8;
  }

  .male {
    width: 160px;
    display: flex;
    justify-content: space-between;

    .eye-left,
    .eye-right {
      width: 20px;
      height: 25px;
      position: relative;
      background-color: #ba300e;
      border-radius: 50% 50% 60% 60% / 50% 50% 60% 60%;

      &::before,
      &::after {
        content: "";
        display: block;
        border-radius: 50%;
        background-color: #fff;
        position: absolute;
      }

      &::before {
        width: 8px;
        height: 8px;
      }

      &::after {
        width: 3px;
        height: 3px;
      }
    }

    .eye-left {
      transform: rotate(-45deg);

      &::before {
        top: 6px;
        left: 10px;
      }

      &::after {
        top: 5px;
        left: 3px;
      }
    }

    .eye-right {
      transform: rotate(45deg);
      &::before {
        top: 5px;
        right: 10px;
      }

      &::after {
        top: 2px;
        right: 5px;
      }
    }
  }
</style>

<div class="male">
  <div class="eye-left"></div>
  <div class="eye-right"></div>
</div>

三、兔子嘴巴

嘴巴部分, 简单来看其实就是一个带有 圆角三角形, 其实如果只是一个三角形那么这里其实完全可以通过 border 来实现, 但偏偏这里是带有圆角的, 那么通过 border 是没法直接实现的;

所以需要换个思路, 如下图所示可以通过三个圆角的菱形、拼凑而成!

image

那么问题就回到如果设置一个菱形了, 这里可以使用 transform 实现, 下面直接看完整代码…

<style>
  body {
    padding: 100px;
    background-color: #c9daf8;
  }

  .mouth {
    width: 10px;
    height: 10px;

    background-color: rgba(255, 0, 0, 0.5);

    border-bottom-left-radius: 3px;
    transform: rotate(327deg) skewX(20deg) scale(1, 0.866);

    &::before,
    &::after {
      content: "";
      width: 100%;
      height: 100%;
      display: block;

      background-color: inherit;
      border-bottom-left-radius: 4px;
    }

    &::before {
      background-color: rgba(0, 255, 0, 0.5);
      transform: rotate(135deg) skewY(-45deg) scale(0.707, 1.414) translate(-50%, 0);
    }

    &::after {
      background-color: rgba(0, 0, 255, 0.5);
      transform: rotate(-135deg) skewX(-45deg) scale(1.414, 0.707) translate(100%, 150%);
    }
  }
</style>
<div class="mouth"></div>

四、眉毛

如图, 是 眉毛 的一个绘制过程

  • 由一个正方形绘制而成
  • 首先设置圆角, 变成一个扇形
  • 通过 box-shadow 在扇形弧度的边缘绘制边框(也就是眉毛部分)
  • 移除背景色: 最初为了调试方便所以设置了一个背景色, 所以需要移除
  • 最后通过 transform 将眉毛旋转到正确位置

image

  1. 基础结构: 下面是基础代码, 一个 div 配合两个伪元素(::after::before)创建两个正方形, 并设置了基础宽高、背景色
<style>
  .eyebrow {
    width: 40px;
    display: flex;
    justify-content: space-between;

    &::after,
    &::before {
      content: "";
      width: 14px;
      height: 14px;
      display: block;
      background-color: #ff7875;
    }
  }
</style>

<div class="eyebrow"></div>
  1. 设置圆角: 通过 border-radius 为左上角设置一个圆角, 完成一个扇形的绘制
<style>
  .eyebrow {
    ...

    &::after,
    &::before {
      ...
+     border-top-left-radius: 100%;
    }
  }
</style>
  1. 设置投影: 这里通过 box-shadow 来设置投影, 投影在 x 轴和 y 轴的偏移都设置为 -1px 这样的话就产生一个弧线
<style>
  .eyebrow {
    ...
    
    &::after,
    &::before {
      ...
+     box-shadow: -1px -1px #290604;
    }
  }
</style>
  1. 移除背景色: 这里背景色是多余的, 最初之所以设置了背景色, 是为了调试方便才设置了一个背景色, 所以这里需要移除掉
<style>
  .eyebrow {
    ...
    &::after,
    &::before {
      ...
-     background-color: #ff7875;
      ...
    }
  }
</style>
  1. 旋转: 最后最后通过 transform 为将眉毛调整下角度
<style>
  .eyebrow {
    ....

    &::after,
    &::before {
      ...
+     transform: rotate(45deg);
    }
  }
</style>
  1. 下面是本节, 也就是 眉毛 部分的一个完整的实现代码
<style>
  body {
    padding: 100px;
    background-color: #c9daf8;
  }

  .eyebrow {
    width: 40px;
    display: flex;
    justify-content: space-between;

    &::after,
    &::before {
      content: "";
      width: 14px;
      height: 14px;
      display: block;
      border-top-left-radius: 100%;
      box-shadow: -1px -1px #290604;
      transform: rotate(45deg);
    }
  }
</style>

<div class="eyebrow"></div>

五、母兔大眼睛

母兔眼睛绘制起来相对会麻烦一点, 这里我们将进行拆解成三部分进行讲解: 眼睫毛、眼球、下睫毛

5.1 眼睫毛

如图, 是 眼睫毛 的一个绘制过程

  • 由两个正方形绘制而成
  • 首先设置圆角, 变成两个扇形
  • 通过 border 设置 右边框, 和 圆角 配合就形成一个睫毛
  • 移除背景色: 最初为了调试方便所以设置了一个背景色, 所以需要移除
  • 最后通过 transform 将睫毛偏移、旋转到正确位置

image

  1. 基本结构: 由一个 div 中的两个伪元素(::before::after)生成两个正方形, 并设置了基础宽高、背景色
<style>
  .eyelid {
    &::after,
    &::before {
      content: "";
      width: 6px;
      height: 6px;
      display: block;
      background-color: #ff7875;
    }
  }
</style>
<div class="eyelid"></div>
  1. 设置圆角: 通过 border-radius 为两个正方形的右上角设置一个圆角, 形成两个扇形
<style>
  .eyelid {
    &::after,
    &::before {
      ...
+     border-top-right-radius: 100%;
    }
  }
</style>
  1. 设置边框: 通过 border 设置一个 右边框, 这时与 圆角 结合就会形成一个小睫毛
<style>
  .eyelid {
    &::after,
    &::before {
      ...
+     border-right: 2px solid #290604;
    }
  }
</style>
  1. 移除背景色: 这里背景色是多余的, 最初之所以设置了背景色, 是为了调试方便才设置了一个背景色, 所以这里需要移除掉
<style>
  .eyelid {
    &::after,
    &::before {
      ...
-     background-color: #ff7875;
      ...
    }
  }
</style>
  1. 旋转偏移: 最后就是通过 transform 将两个睫毛通过偏移、旋转组合在一起
<style>
  .eyelid {
    &::after,
    &::before {
      ...
    }

+   &::before {
+     transform-origin: bottom right;
+     transform: translateY(100%) rotate(40deg);
+   } 
  }
</style>
  1. 下面是本节, 也就是 眼睫毛 部分的一个完整的实现代码
<style>
  body {
    padding: 100px;
    background-color: #c9daf8;
  }

  .eyelid {
    &::after,
    &::before {
      content: "";
      width: 6px;
      height: 6px;
      display: block;
      border-top-right-radius: 100%;
      border-right: 2px solid #290604;
    }

    &::before {
      transform-origin: bottom right;
      transform: translateY(100%) rotate(40deg);
    } 
  }
</style>

<div class="eyelid"></div>

5.2 眼球

如图, 是 眼球 的一个绘制过程

  • 由三个正方形绘制而成
  • 首先设置圆角, 变成三个圆
  • 通过 border 为最外层圆形(眼球)设置边框
  • 通过 position 将眼白定位到正确的位置
  • 最后通过 box-shadow 给眼白设置一个阴影, 简单过渡下

image

  1. 基本结构: 通过一个 div 配合两个伪元素(::before::after)绘制三个正方形, 并设置了基础宽高、背景色
<style>
  .eye {
    width: 20px;
    height: 20px;
    position: relative;
    background-color: #fff;

    &::before,
    &::after {
      content: "";
      display: block;
      position: absolute;
    }

    &::before {
      width: 8px;
      height: 8px;
      background-color: #360703;
    }

    &::after {
      width: 2px;
      height: 2px;
      background-color: #fff;
    }
  }
</style>
<div class="eye"></div>
  1. 设置圆角: 通过 border-radius 将正方形转为圆形
<style>
  .eye {
    ...
+   border-radius: 50%;
    
    &::before,
    &::after {
      content: "";
      ...
+     border-radius: 50%;
    }

    ...
  }
</style>
  1. 设置边框: 通过 border 为最外层圆形(眼球)设置边框
<style>
  .eye {
    ...
+   border: 2px solid #290604;
    
    ...
  }
</style>
  1. 定位组合: 使用 position 将眼白定位到正确的位置
<style>
  .eye {
    ...

    &::before {
      ...
+     right: 1px;
+     bottom: 1px;
      background-color: #360703;
    }

    &::after {
      ...
+     right: 2px;
+     bottom: 3px;
      background-color: #fff;
    }
  }
</style>
  1. 设置阴影: 通过 box-shadow 为眼白设置一个白色阴影, 目的只是为了让过滤自然点
<style>
  .eye {
    ...

    &::after {
      ...
+     box-shadow: 0 0 2px #fff;
      background-color: #fff;
    }
  }
</style>
  1. 下面是本节, 也就是 眼球 部分的一个完整的实现代码
<style>
  body {
    padding: 100px;
    background-color: #c9daf8;
  }
  .eye {
    width: 20px;
    height: 20px;
    position: relative;
    background-color: #fff;
    border-radius: 50%;
    border: 2px solid #290604;
    
    &::before,
    &::after {
      content: "";
      display: block;
      position: absolute;
      border-radius: 50%;
    }

    &::before {
      width: 8px;
      height: 8px;
      right: 1px;
      bottom: 1px;
      background-color: #360703;
    }

    &::after {
      width: 2px;
      height: 2px;
      right: 2px;
      bottom: 3px;
      box-shadow: 0 0 2px #fff;
      background-color: #fff;
    }
  }
</style>
<div class="eye"></div>

5.3 下睫毛

这部分的实现方案, 和眉毛部分基本是一样的!! 这里就不一一展开了, 下面直接看代码

<style>
  body {
    padding: 100px;
    background-color: #c9daf8;
  }

  .eyelid {
    width: 10px;
    height: 10px;
    border-radius: 100% 0 0;

    background-color: #f8ded9;
    box-shadow: -1px -1px 0 0 #290604;
    transform: rotate(23deg);
  }

</style>
<div class="eyelid"></div>

5.4 合并

最后一步, 如图所示, 就是将上面完成的几个小部件, 通过定位也好, 偏移也好将它们组合合并起来, 这里就不展开了…

image

六、腮红

最后再顺便讲解下, 腮红 的实现!! 这里其实是通过 box-shadow 实现的, 相对比较很简单, 直接看代码

<style>
  body {
    padding: 100px;
    background-color: #c9daf8;
  }

  .blusher {
    width: 0;
    height: 0;
    display: block;

    top: 48px;
    position: absolute;

    border-radius: 50%;
    background-color: #e68d84;
    box-shadow: 0 0 10px 8px #e68d84;
  }

</style>
<div class="blusher"></div>

最后的结果大概就如图所示:

image

七、总结

到此, 情侣兔 绘制难点基本都已经讲到了, 剩下的工作其实就是将它们进行合并、组装起来, 具体的细节这里就不展开了!!!最后再贴下几个源码链接:


image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值