本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
看到微信聊天中的表情很有趣,于是尝试使用一个标签和css
去实现发呆的表情,本文记叙了实现的思路。
微信表情原图:
效果
基本思路
可以看到表情中的元素还是比较多的,有眼睛(眼白,瞳孔)、腮红、嘴巴、眉毛这些。
虽然看上去元素挺多的,但是仔细看去,其实就是两个形状,眼睛、腮红、嘴巴都是原型,就眉毛是两条不同方向的直线,都是比较简单的图形。
那么思路就很简单了,无非就是实现这两个图形。但是元素不够如何处理,div
加上两个伪元素,勉强算是三个标签,不够实现表情的所有元素。这个时候就需要box-shadow
来帮忙了,它可以重复元素的形状并且自定义位置,最主要的是,阴影可以存在多个。
代码
HTML布局
这个没什么好说的,就一个div
:
<div class="daze"></div>
样式
- 首先从脸开始,很简单的一个圆,设定好其宽度和高度,还有
border-radius
,加上肤色,代码如下:
.daze {
width: 100px;
height: 100px;
background: radial-gradient(rgb(247, 229, 126), rgb(246, 212, 65));
border-radius: 50%;
position: relative;
}
加上样式可以看到一个大圆脸:
- 然后是脸上部件,先把那些圆形的处理起来,包括眼睛,嘴巴,腮红;先使用
::before
画一个瞳孔,顺便固定其位置:
.daze::before {
content: '';
width: 15px;
height: 15px;
background: #000;
border-radius: 50%;
/* 使用绝对定位调整位置 */
position: absolute;
top: 35px;
left: 20px;
}
然后就是使用最主要的box-shadow
,先用它原地画一个眼白,注意不要设置模糊程度:
/* 眼睛和嘴巴 */
.daze::before {
content: '';
width: 15px;
height: 15px;
background: #000;
border-radius: 50%;
position: absolute;
top: 35px;
left: 20px;
// 设定阴影
box-shadow: 0px 0px 0 10px #fff;
}
一只眼睛就基本画出来了,用同样的阴影处理就可以画出第二只眼睛,不过要注意的位置的调整,两只眼睛是轴对称的,所以要确定好位置。
因为在本文中设定脸的宽度为100px
,瞳孔为15px
,位置上left: 20px
,所以,另一个眼睛在x
轴上的相对距离为脸宽度 - 两个瞳孔宽度及它们距离左右边界的距离 + 左侧瞳孔宽度
即100px - (15px + 20px) * 2 + 15px = 45px
,距离算好,自然是添加阴影,把另一个眼睛画出来:
box-shadow:
0px 0px 0 10px #fff,
45px 0px #000,
45px 0px 0 10px #fff;
用同样的思路和方法,画出腮红和嘴巴,需要注意的是,除了腮红需要模糊之外,其他元素都不需要模糊,完整的box-shadow
设置如下:
box-shadow:
/* 第一只眼睛眼白 */
0px 0px 0 10px #fff,
/* 第二只眼睛的瞳孔和眼白 */
45px 0px #000,
45px 0px 0 10px #fff,
/* 嘴巴 */
22.5px 30px rgb(200, 135, 48),
/* 两侧的腮红,需要模糊 */
-12px 15px 15px 5px rgba(244, 117, 17, 0.6),
57px 15px 15px 5px rgba(244, 117, 17, 0.6);
- 最后就是眉毛,只剩下一个
::after
伪元素了,但是无法再和上面一样使用box-shadow
复制形状的做法了,因为box-shadow
只能复制元素本身的形状,虽然两边的眉毛形状相同,但是指向方向不同。
最终的决解方法就是,将::after
设置成为菱形,旋转45deg
,放在眼睛中间:
.daze::after {
content: '';
position: absolute;
width: 40px;
height: 40px;
top: -10px;
left: 30px;
background: rgb(158, 112, 58);
// 设置旋转和倾斜
transform: rotateZ(45deg) skew(-10deg, -10deg);
}
然后不是使用阴影复制形状了,而是普通地使用阴影分别向两个红色箭头的指向露出一点阴影,使其看起来像两条眉毛,然后将::after
本身设置为透明,最终样式为:
.daze::after {
content: '';
position: absolute;
width: 40px;
height: 40px;
top: -10px;
left: 30px;
background: transparent;
transform: rotateZ(45deg) skew(-10deg, -10deg);
box-shadow: 0px 3px rgb(158, 112, 58), 3px 0 rgb(158, 112, 58);
}