咱们在平时的网页中,常常会见到这样的优惠券或者其余的券(特征就是会有反方向的圆角)。html
可能大部分前端人员为了简单,直接采用图片的方式,直接把整张图做为背景。其实这也没什么很差的,简单,方便,尚未兼容性问题,ie6跑起来都没得问题。前端
若是不考虑那些低旧浏览器的话,仍是有办法直接用css来实现,有几个好处css3
1.扩展方便,好比以前是300 100的,如今要改为300 150的,就一行代码的事
2.没有图片,加载起来也更快了,也节省了带宽程序员
咱们先实现大体的框架,左右两部分浏览器
<style> html,body{ box-sizing:border-box; margin:0; padding:20px; height:100%; background:#fadaa7; } .coupon{ display:inline-block; overflow:hidden; border-radius:10px; } .coupon-left{ float:left; width:150px; height:150px; background:#252525; } .coupon-con{ float:left; width:350px; height:150px; background:#fff; } </style> <div class="coupon"> <div class="coupon-left"></div> <div class="coupon-con"></div> </div>
下面就来实现中间看着比较复杂的"凹槽"部分框架
我能想到跟圆角相关的有圆角、圆形、径向...这些吧svg
有人说svg
也能够,确实svg
什么均可以作,不光是这种形状,只要画个路径,填充一下就完事,这个比较通用,并非这个特例,因此在这里不讨论用这个方式。
还有一个缘由,svg
生成的形状也是固定了的,只能等比缩放,不能作其余自适应了。wordpress
看到这样的形状,通常人可能会想会不会能够用border-radius
的负值呢,毕竟像margin
那些,使用负值每每能够带来意想不到的效果spa
.con{ border-radius:-10px; }
很惋惜,这种写法根本就是不合法的,在谷歌浏览器上打开控制台能够看到直接被删除了。
虽说这种思路不行,可是咱们能够换一种思路。
假设咱们如今有一个圆,它自己没有颜色,可是它有一个黑色的边框
如今咱们想象一下,假如这个圆的边框愈来愈大,外面有个容器若是超出就会隐藏,会发生什么呢
若是这个圆在右下角,那么就变成了这样
这不就是咱们须要的吗?
如今咱们用css来实现
根据上面的分析,咱们背景的颜色应该是圆的边框的颜色,因此原背景要去掉
.coupon-left{ position:relative; overflow:hidden; /*background:#252525*/ } /*为了减小html的结构,咱们使用伪元素*/ .coupon-left::before{ position:absolute; width:20px; height:20px; top:-210px; right:-210px; border-radius:50%; border:200px solid #252525;/*边框只要可以覆盖整个容器就行*/ }
这样就实现了一个凹槽。
原本觉得这样下去,复制一下,改写一下就完事了的,结果发现没这么简单,由于如今形状是被裁剪出来的,因此咱们不能让上一个圆角把整个都覆盖,否则下面的圆角就出不来了,这时咱们要用到clip
裁剪功能
关于clip
这里简单介绍一下,咱们通常会用到rect
这个功能,有四个值,分别是上右下左
clip: rect(<top>, <right>, <bottom>, <left>);
这里咱们改造一下咱们刚才写的样式,添加以下代码
.coupon-left::before{ clip: rect(0,210px,285px,0); }
这样就和下半部分隔离开来了,下面作下半部分的凹槽,咱们用::after
,写法彻底一致,注意一下坐标就好了
.coupon-left::after{ content: ''; position: absolute; top: -210px; display: block; right: -210px; width: 20px; height: 20px; border-radius: 50%; border: 200px solid #252525; clip: rect(135px,210px,285px,0); }
这样就完美的实现了两个凹槽,右边的原理一样,下面是完整的css代码
html,body{ box-sizing:border-box; margin:0; padding:20px; height:100%; background:#fadaa7; } .coupon{ display:inline-block; overflow:hidden; border-radius:10px; } .coupon-left{ float:left; width:150px; height:150px; position:relative; } .coupon-left::before{ content: ''; position: absolute; top: -210px; display: block; right: -210px; width: 20px; height: 20px; border-radius: 50%; border: 200px solid #252525; clip: rect(0,210px,285px,0); } .coupon-left::after{ content: ''; position: absolute; bottom: -210px; display: block; right: -210px; width: 20px; height: 20px; border-radius: 50%; border: 200px solid #252525; clip: rect(135px,210px,285px,0); } .coupon-con{ float:left; width:350px; height:150px; position:relative; } .coupon-con::before{ content: ''; position: absolute; top: -410px; display: block; left: -410px; width: 20px; height: 20px; border-radius: 50%; border: 400px solid #fff; clip: rect(0,800px,485px,410px); } .coupon-con::after{ content: ''; position: absolute; bottom: -410px; display: block; left: -410px; width: 20px; height: 20px; border-radius: 50%; border: 400px solid #fff; clip: rect(335px,800px,485px,410px); }
下面是codepen演示
https://codepen.io/xboxyan/pe...
还有一个思路就是径向渐变。
关于径向渐变的具体使用能够参考张鑫旭的文章CSS3 radial-gradient径向渐变语法及辅助理解案例10则
那么怎样实现咱们要的效果呢
咱们先看看径向渐变的语法
radial-gradient([[<shape> || <size>] [at <position>]?,| at <position>,]?<color-stop>[,<color-stop>]+);
径向渐变由它的中心定义。
用法
{ background:radial-gradient(circle at 50px 50px, yellow, orange 33.33%, red 66.666%, white) }
咱们把渐变的颜色改为透明到黑色的渐变
{ background:radial-gradient(circle at 50px 50px, transparent, #252525) }
如今把透明的部分给一个距离,灰色的部分也给一个距离,让他们以前的渐变区域重合,就变成纯色了
{ background:radial-gradient(circle at 50px 50px, transparent 20px, #252525 20px) }
如今把这个空心圆移到边缘
{ background:radial-gradient(circle at right top, transparent 20px, #252525 20px) }
如今就是如何作出两个凹槽的问题
咱们有两种方式,一种是和上面的同样,用两个伪元素拼接而成,第二种就是直接利用css3的多背景拼接
咱们先说说第二种
{ background:radial-gradient(circle at right top, transparent 20px, #252525 20px, #252525 100px, transparent 100px),radial-gradient(circle at right bottom, transparent 20px, #252525 20px, #252525 100px, transparent 100px) }
咱们能够继续拼接,可能能够实现咱们想要的效果
如今来讲说第一种方法
咱们把代码放入咱们的例子当中
.coupon-left::before{ content: ''; position: absolute; top: 0; left: 0; right:0; height:50%; background:radial-gradient(circle at right top, transparent 10px, #252525 10px, #252525 10px) } .coupon-left::after{ content: ''; position: absolute; bottom: 0; left: 0; right:0; height:50%; background:radial-gradient(circle at right bottom, transparent 10px, #252525 10px, #252525 10px) } .coupon-con::before{ content: ''; position: absolute; top: 0; left: 0; right:0; height:50%; background:radial-gradient(circle at left top, transparent 10px, #252525 10px, #fff 10px) } .coupon-con::after{ content: ''; position: absolute; bottom: 0; left: 0; right:0; height:50%; background:radial-gradient(circle at left bottom, transparent 10px, #252525 10px, #fff 10px)
怎么样,是否是很方便?里面都是相对值,意味着有更好的适应性
下面是codepen演示
https://codepen.io/xboxyan/pe...
相比于用圆形来实现,这种径向渐变动方便扩展,写起来也容易。
可是并非说圆形的思路不对,若是只是作一个圆形缺口的话,那种写法更方便,在思惟上,也更领先一步,更能锻炼一我的的空间思考和想象能力,更有设计师角度的意味,这大概是和通常程序员思惟最大的不一样之处吧径向渐变一直以来的兼容性问题要比圆角大的多,每种浏览器内核的写法都不尽相同,虽然目前都基本支持标准写法了,但平时的项目仍是要注意一些。实在是兼容性要求,那只能用图片代替了,谁叫客户第一呢