做一个像真杯子的假杯子
为了完成这个月的目标,我真是把压箱底的内容都拿出来了,这篇文章里的代码素材还是我最早学前端 css 样式时随手画着玩的一个内容,当时的学习热情真的高涨啊,从有想法到一点一点完善到最终完成,期间学了很多关于样式的知识,虽然今后的项目中可能永远也不一定用得到,但是当时真的是为了兴趣想完善心中的想法而学的,没有什么功利心,现在对一个前端老油条来说,这种感觉还是难能可贵,所以与其将此文作为一篇技术文,我更愿意将它当成我的一篇回忆文,回忆入行前端的点点滴滴
缘起一个随手拍
当正在学 css 的渐变内容,随手拍了张照片,是我的保温杯 随之就有个想法,css 能实现渐变效果,那么能不能用渐变效果将杯子的金属质感实现出来? 随后就开始动手做,先将照片导入到 ps 中,测量总宽度 以及每个突出颜色位置的颜色,将杯身分成几分,每一份的顶点是杯子颜色渐变临界点,一点一点将杯子的杯身实现出来。
杯身主要代码
#mainBody {
height: 475px;
width: 200px;
margin: 0px auto;
background: linear-gradient(
90deg,
rgba(105, 102, 87, 1) 0px,
rgba(108, 96, 70, 1) 20px,
rgba(232, 211, 158, 1) 36px,
rgba(232, 211, 158, 1) 40px,
rgba(122, 105, 62, 1) 50px,
rgba(122, 105, 62, 1) 54px,
rgba(238, 216, 165, 1) 67px,
rgba(238, 216, 165, 1) 72px,
rgba(194, 173, 120, 1) 78px,
rgba(194, 173, 120, 1) 81px,
rgba(130, 103, 48, 1) 100px,
rgba(145, 114, 57, 1) 115px,
rgba(117, 96, 49, 1) 131px,
rgba(63, 44, 14, 1) 189px
);
position: relative;
}
很容易就模拟出金属那种拉丝质感了有木有。这里的样式主要用到了 background 的 linear-gradient 这个函数,mdn 对它的解释是:
CSS linear-gradient() 函数用于创建一个表示两种或多种颜色线性渐变的图片。其结果属于<gradient>数据类型,是一种特别的<image>数据类型。
demo:
/* 渐变轴为45度,从蓝色渐变到红色 */
linear-gradient(45deg, blue, red);
/* 从右下到左上、从蓝色渐变到红色 */
linear-gradient(to left top, blue, red);
/* 从下到上,从蓝色开始渐变、到高度 40% 位置是绿色渐变开始、最后以红色结束 */
linear-gradient(0deg, blue, green 40%, red);
大家可以在代码里自由尝试 现在回头看 MDN 的内容,突然发现文档 demo 是百分比并没有说明 rgba 后面可以跟 px,所以我已经不知道当时是怎么了解到可以精确到 px 了。估计当时疯狂查资料才看到的。 简单来说这个特性可以定义一个过渡效果,你可以过度 2 个颜色,也可以过度 n 个颜色。上面我定义杯子的颜色是各种测量位置/读位置颜色后获得的值,可以看到有 14 个不同的值,这些值之间的颜色是平滑过渡的,如果两个颜色是相同的,例如
rgba(122, 105, 62, 1) 50px,
rgba(122, 105, 62, 1) 54px,
那么会保持这个颜色 4px。
平时是不是只用 border-radius: 50%或者 border-radius: 5px 5px 10px 10px 比较多?但是实际上他可以分别定义每个角的横纵距离。对于过多的用法,可以参考 demo
border-radius: 4px 3px 6px / 2px 4px;
/* top topright-bottomleft bottom 四个角横向曲率 */
/* left right 四个角纵向曲率*/
/* 等价于: */
border-top-left-radius: 4px 2px; /*椭圆半长轴 横向曲率 椭圆半短轴 纵向曲率*/
border-top-right-radius: 3px 4px;
border-bottom-right-radius: 6px 2px;
border-bottom-left-radius: 3px 4px;
这里对 border-radius 做了拆解,可以分别控制 box 的四个角的不同曲率。大家可以理解为将一个基础椭圆横向纵向分别切 1 刀分成四等份,在分好后可以再分别定义这四分的半长轴和半短轴,能定义成什么样的形状取决于四个角定义的半长轴,半短轴是什么样,如果是 50%,那没得说,就是一个圆的 4 分之一的曲率,如果是 border-radius: 4px 3px 6px 3px/ 2px 4px; 则对应 左上横 右上横 右下横 左下横 /左上右下纵 右上左下纵,看起来有点绕?没关系自己实际实践一下就理解了,或者怕忘记直接收藏本文回头用到了再翻出来看。
加一点阴影 和曲线
#mainBody {
···
box-shadow: 0px 5px 5px #666;
border-radius: 10px 10px 100px 100px/5px 5px 60px 60px;
}
后续的阴影和曲线,是不是有那么点感觉了,主要是润色一下
让杯子顶部两个角和底部有弧度的感觉
曲线部分解决了,接下来完善一些细节。
可以看到杯子的两侧并不是完全垂直的,有个腰线,在实现腰线时就用到了刚刚 border-radius 的知识,在左右两侧各添加一个 div,并将这个 div 的 border-radios 设置为小横向大纵向的样式: 就这样杯子有了腰线又像了一点
/*左侧:*/
border-radius: 0px 7px 9px 0px/0px 122px 200px 0px;
/*右侧:*/
border-radius: 7px 0px 0px 9px/122px 0px 0px 200px;
给杯子补上两条线
之所以要补两条线,是因为一条线不能同时模拟出光线照到金属上的金属光泽和因为凹陷导致的阴影。 高光这条线还是传统 border-radius 和 background: linear-gradient 搭配 需要注意的是阴影这条线需要将 border 的左右宽度设为 0。这时顺带补上了文字,没什么好说的,稍微用 transform 给文字缩放了一下让文字看起来更瘦
来完善顶部
杯子没有完全拧严,所以杯盖和杯体又一定空隙,这个空隙也用一个 div 模拟出来,还是标准操作,background: linear-gradient + border-radius
并且用左右两个小 div div3 div4 模拟出这部分的曲线
就这样杯身基本上搞定了,接下来完善杯盖
杯盖本体:
同杯体一样杯盖也有光泽渐变的效果,所以如法炮制添加渐变
.cupTop {
display: none;
display: block;
position: relative;
margin: 0 auto 3px;
width: 200px;
height: 94px;
background: linear-gradient(
90deg,
rgba(198, 213, 210, 1) 0px,
rgba(198, 213, 210, 1) 10px,
rgba(229, 241, 237, 1) 45px,
rgba(229, 241, 237, 1) 64px,
rgba(142, 147, 140, 1) 200px
);
border-radius: 36px 36px 0px 0px/33px 33px 0px 0px;
z-index: 20;
}
和实体杯盖对比还缺少三个点,并且这三个点有些反光角度,继续添加三个点:
.dot1 {
display: inline-block;
vertical-align: top;
width: 9px;
height: 9px;
border-radius: 50%;
margin: 3px 4px 3px 5px;
background: linear-gradient(
-60deg,
rgba(174, 179, 173, 1) 0px,
rgba(238, 244, 240, 1) 9px
);
}
接下来是杯盖顶部又个小小的弧线,这里当时怎么用杯盖模拟曲线都不理想,所以干脆再拼一个元素
.div1 {
position: absolute;
top: -3px;
left: 50%;
margin-left: -73px;
width: 146px;
height: 5px;
border-radius: 50%;
border-radius: 115px 115px 0px 0px/10px 10px 0px 0px;
background: linear-gradient(
90deg,
rgba(220, 230, 227, 1) 0px,
rgba(229, 241, 237, 1) 18px,
rgba(229, 241, 237, 1) 37px,
rgba(164, 169, 164, 1) 142px
);
}
杯子顶部就有了一个弧度效果。
大功告成
好了,最终效果就是这样了,整体代码依然在 GitHub 上,大家要是有什么好玩的想法或者有任何完善欢迎继续提交pr
我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿。