CSS-单个div实现精灵球

1,309 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

前言

最近发现了一个有趣的网站,里面的每一个图形,都是由一个 div 加上 CSS 完成的,部分图形如下: 微信截图_20220806150254.png 下面这幅图,也是只由一个 div 完成的: 微信截图_20220806150316.png 同样是 div + CSS,为别人可以这么秀啊😂。

通过源码的学习,试着模仿写了一个比较简单的精灵球。

效果

基本原理

所有图形,基本上都是可以拆解成矩形圆形椭圆这三个基本图形,线条其实就是比较细的矩形,而就是比较短的线条

通过 CSSlinear-gradientradial-gradient 基本上就可以实现矩形圆形椭圆这三个基本图形,在通过 background-position 调整图形的位置,background-size 调整图形的大小即可。

注意:background-image 可以设置多个渐变,按照写入的顺序,越先写入的渐变,层级越高,会挡住后面写入渐变,可以理解为 z-index

精灵球

精灵球整体是一个圆形,所以需要先定义一个圆形的 div,代码如下:

.ball {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background-color: skyblue;
}

微信截图_20220806152300.png

然后可以划分一下区域,精灵球上半部分为红色,中间为黑色,下半部分为白色,而且黑色部分左右还留有一点透明,可以设置宽度的时候,不用设置成 100%,然后居中处理即可。

不同区域的实现,基本上就是通过颜色渐变,在需要显示特定颜色的区域设定好颜色,其他区域设定为透明,有点类似于 PS 的图层,这里每一个区域可以理解为就是一个图层,代码如下:

.ball {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background-color: transparent;
  background-image: 
    /* 红色区域,从上往下,48%之前都是红色,48%之后就是透明 */
    linear-gradient(to bottom, rgb(253, 1, 1) 48%, transparent 48%), 
    /* 黑色区域 48% ~ 52% 之间是黑色,其他透视透明 */
    linear-gradient(to bottom, transparent 48%, #000 48%, #000 52%, transparent 52%), 
    /* 白色区域 同红色区域的原理 */
    linear-gradient(to bottom, transparent 52%, rgb(254, 254, 254) 52%) 
 ;
 background-size:
    100% 100%, /* 红色区域的大小为100% */
    96% 100%, /* 黑色区域 略窄于红色区域,因此宽度设定于 100% */
    100% 100% /* 白色区域的大小为100% */
 ;
 background-position:
    0 0, /* 红色区域的起始位是 0 0 */
    50% 0, /* 黑色区域因为宽度不是100%,需要在x轴上居中处理,因此设定为 50% */
    0 0 /* 白色区域的起始位是 0 0 */
 ;
}

微信截图_20220806153852.png

然后就是中间部分的按钮了,因为按钮必须显示在最前面,所以写的时候,也要写在前面;而且按钮都是原型的,可以使用 radial-gradient 实现,在需要显示特定颜色的区域设定好颜色,其他区域设定为透明。

其他区域设置为透明,是为了不挡到其他的渐变效果。

.ball {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background-color: transparent;
  background-image: 
    /* 最里层按钮,因为同第二层一样都是白色的,所以这里就是只是使用一个圆环模拟 */
    radial-gradient(circle, transparent 11%, #a1a1aa 12%, transparent 12%),
    /* 第二层按钮,0% ~ 16%都为白色,再往外就是透明 */
    radial-gradient(circle, #fff 16%, transparent 16%),
    /* 最外层黑色部分,0% ~ 20%都为白色,再往外就是透明  */
    radial-gradient(circle, #000 20%, transparent 20%),
    linear-gradient(to bottom, rgb(253, 1, 1) 48%, transparent 48%),
    linear-gradient(to bottom, transparent 48%, #000 48%, #000 52%, transparent 52%),
    linear-gradient(to bottom, transparent 52%, rgb(254, 254, 254) 52%)
  ;
  background-repeat: no-repeat;
  background-size:
    100% 100%, /* 最里层按钮的大小,这里设定的其实是渐变图层的大小,并不是按钮的显示大小 */
    100% 100%, /* 第二层按钮的大小 */
    100% 100%, /* 最外层黑色部分的大小 */
    100% 100%,
    96% 100%,
    100% 100%
  ;
  background-position:
    0 0, /* 最里层按钮的位置 */
    0 0, /* 第二层按钮的位置 */
    0 0, /* 最外层黑色部分的位置 */
    0 0,
    50% 0,
    0 0
  ;
}

微信截图_20220806154848.png

一个精灵球基本上就完成了,但是看上去不够真实,可以考虑打点光,其实就是再加上两层渐变:

  1. 一层从左上角往右下角,从白色到透明,逐渐变化,模拟光照;
  2. 一层从右下角往左上角,从黑色到透明,逐渐变化,模拟阴影。
.ball {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background-color: transparent;
  background-image: 
    /* 光照 */
    linear-gradient(to right bottom, rgba(255, 255, 255, .5), transparent),
    /* 阴影 */
    linear-gradient(to top left, rgba(0, 0, 0, .5), transparent 50%),
    radial-gradient(circle, transparent 11%, #a1a1aa 12%, transparent 12%),
    radial-gradient(circle, #fff 16%, transparent 16%),
    radial-gradient(circle, #000 20%, transparent 20%),
    linear-gradient(to bottom, rgb(253, 1, 1) 48%, transparent 48%),
    linear-gradient(to bottom, transparent 48%, #000 48%, #000 52%, transparent 52%),
    linear-gradient(to bottom, transparent 52%, rgb(254, 254, 254) 52%)
  ;
  background-repeat: no-repeat;
  background-size:
    /* 光照和阴影都不需要 100% 的高度,48%足够 */
    100% 48%,
    100% 48%,
    100% 100%,
    100% 100%,
    100% 100%,
    100% 100%,
    96% 100%,
    100% 100%
  ;
  background-position:
    /* 光照的起始位置 */
    0 0,
    /* 阴影的起始位置 */
    0 0,
    0 0,
    0 0,
    0 0,
    0 0,
    50% 0,
    0 0
  ;

微信截图_20220806145841.png

到这里就基本完成了,等以后更加熟悉,可以考虑搞一个更加复杂的图形出来。