前言
CSS画图系列又来了。通过这种形式去了解CSS倒也是一种很不错的方式。今日前端早读课文章由滴滴
几木投稿分享。王宏宇,也叫几木,爱好自驾撸猫烫头,来自滴滴小桔车服,致力于体验和产研效率提升正文从这开始~~
冰墩墩(英文:BingDwenDwen,汉语拼音:bīngdūndūn),是年北京冬季奥运会的吉祥物。将熊猫形象与富有超能量的冰晶外壳相结合,头部外壳造型取自冰雪运动头盔,装饰彩色光环,整体形象酷似航天员。
以前面试总被问,如何用CSS画一个三角形。今天我想玩点大的,用CSS画个冰墩墩!
1基础结构结构划分首先看下官方这张图。
我们可以把各个部分拆成div,再给div分别做CSS,最终拼成整幅图。
divclass="bingdundun-container"divclass="ear"/divdivclass="hand-left"/divdivclass="hand-right"/divdivclass="body"/divdivclass="foot"/divdivclass="face"/divdivclass="eye"/divdivclass="eye-hole"/divdivclass="nose"/divdivclass="mouth"/div/div
对这个分法你可能有很多问号,比如:
一个div能画出这么复杂的东西?
为什么两只眼睛分一个div?为什么瞳孔反而要单独分?
后面的操作会给你答案。
绝对定位和图层然后我们给所有div一个绝对定位:
.bingdundun-container{position:relative;div{position:absolute;}}
这样就像sketch、ps一样,我们有了很多图层。绝对定位下,图层是有上下顺序的,这也是前面划分结构的一个依据。
但CSS的能力不止于此,通过伪元素,一个div理论上可以提供三个图层:自身、before、after。我们给他们也统一加上。
.bingdundun-container{div{:before,:after{position:absolute;content:;}}}2动手
接下来我们要挨个部分画图了,其中夹杂引入属性的简单说明,一口饭一口菜。
身体冰墩墩的身体是一个类似蛋的形状,头顶要比脚下圆润些,这个好做,一组border+radius搞定。
.bingdundun-container{width:px;height:px;left:px;top:px;border:10pxsolid#;background:#fff;border-top-left-radius:px;border-top-right-radius:px;border-bottom-left-radius:pxpx;border-bottom-right-radius:pxpx;}
得到一个蛋
知识点1:border-radius让方盒子圆起来border-radius可以用来实现不规则椭圆。
四个角的radius可以单独设置,每个radius又可以单独设置两个方向的。
耳朵耳朵也差不多,两个蛋,放在一个div里,因为我们前面说过,一个div至多可以提供三个图层
.ear{::before,::after{width:98px;height:px;background:#;border-radius:50%;}::after{left:px;}}
因为div顺序靠前,下半部分正好被身体压掉。
左手左手类似一个水滴的形状,看似可以尝试比较大的borderradius,但实际行不通,可以用一个圆形+一个三角形拼起来。其中三角形用border实现。
.hand-left{width:px;height:px;border-radius:50%;background:#;::before{width:0;height:0;border:50pxsolid;border-color:transparent##transparent;}}知识点2:巧用border画三角形
元素四个方向的border是沿contentbox、borderbox角的连线分割的,可以画出三角形、梯形。
右手右手是一个椭圆+一颗心(拆成两个椭圆拼起来),三个图层正好够用。又引入了transformrotate属性。
.hand-right{width:89px;height:px;background:#;transform:rotate(30deg);border-bottom-right-radius:89px;border-top-left-radius:40px;border-top-right-radius:49px;::before{width:16px;height:30px;transform:rotate(19deg);background:red;border-top-left-radius:8px;border-top-right-radius:8px;border-bottom-left-radius:16px;}::after{width:16px;height:30px;transform:rotate(-71deg);background:red;border-top-left-radius:8px;border-top-right-radius:8px;border-bottom-right-radius:16px;}}知识点3:transform改变元素形状
transform可以改变元素的形状,比如rotate来旋转角度。
除了rotate,skew也常用来实现菱形等。
脚这个脚看起来有点难办,虽然是圆角类似椭圆,但几个方向比较刁钻。这里果断拆分成两部分,一部分堆在身体下,一部分堆在身体上。稍微调整下html。
divclass="foot-bottom"/divdivclass="body"/divdivclass="foot-top"/div
身体下部分
.foot-bottom{left:px;top:px;::before{right:36px;width:px;height:px;background:#;border-top-left-radius:9px90px;border-top-right-radius:9px83px;border-bottom-left-radius:35px;border-bottom-right-radius:14px;}::after{left:36px;width:px;height:px;background:#;border-top-right-radius:9px90px;border-top-left-radius:9px83px;border-bottom-right-radius:35px;border-bottom-left-radius:14px;}}
发现没,两只脚对称,这里的元素本身定到中间,本身没什么意义,但两伪元素就可以对称写了,非常方便。
身体上部分一样对称画。
.foot-top{left:px;top:px;::before{right:38px;width:px;height:37px;background:#;border-top-right-radius:%;}::after{left:38px;width:px;height:37px;background:#;border-top-left-radius:%;}}
正好和身体下的部分叠在一起。
脸的轮廓脸的轮廓是几圈彩色套在一起的。
一圈好办,给个border就好了;三圈也好办,大不了用两个伪元素。更多圈怎么办呢?我们可以用box-shadow。
.face{width:px;height:px;border-top-left-radius:50%60%;border-top-right-radius:50%60%;border-bottom-left-radius:41%42%;border-bottom-right-radius:41%42%;box-shadow:5px#BB0,10px#DC2F1F,15px#1D,20px#EFA90D,25px#;}知识点4:box-shadow强大的复印机
box-shadow可以无限次声明同一个元素的阴影,并可以自定义偏移、扩展、颜色。
这就很有想象空间了,像一个复印机:
调整扩展,可以无限增加元素的border层数,比如上面的用法。
调整偏移,可以把元素形状复制到任意位置。
关键是,任何一次复印都可以单独改变颜色!
眼睛、鼻子、嘴一样思路,用border-radius、transform、border等前面提到的属性
瞳孔这个本来也挺简单,对称两个带border的圆,但有一个小细节,就是瞳孔上水灵灵的眼光,是不对称的。
那怎么办?div自己居中定位不是闲着么,让他用box-shadow打出来就好了。
.eye-hole{width:15px;height:15px;border-radius:50%;box-shadow:-75px19px#fff,81px19px#fff;}
完成
至此,冰墩墩就画完了。
Github预览: