本次我们来看一个带有特殊圆角的导航栏布局,比如谷歌浏览器的标签栏:如何实现这样的布局?下面介绍几种方法1.伪元素拼接假设有这样一个HTML结构SvelteAPISvelteAPISvelteAPISvelteAPI首先考虑的一种方式用两个伪元素拼接中间的圆角比较容易。如何实现左右两侧的反向圆角?其实可以想一下可以实现圆的样式。这里我想到了border-radius。你可以用这种方法画一个透明的圆,给圆加上足够大的边框,或者投射一小部分的剪裁。下面是代码实现。即.tab-item{position:relative;背景色:红色;填充:10px15px;边界半径:12px12px00;游标:指针;转换:.2s;}.tab-item::before,.tab-item::after{position:absolute;底部:0;内容:'';宽度:20px;高度:20px;边界半径:100%;box-shadow:00040pxred;/*使用box-shadow不影响大小*/t??ransition:.2s;}.tab-item::before{left:-20px;clip-path:inset(50%-10px050%);}.tab-item::after{right:-20px;clip-path:inset(50%50%0-10px);}最终实时效果如下这里用cl做裁剪ip路径。注意左右可以剪的稍微向内一点,避免拼接出现缝隙。完成代码后,您可以访问chrome-tab(codepen.io)。当然这里的反圆角也可以通过径向渐变来实现,再往下看2.万能的渐变CSS渐变几乎是万能的,什么图形都能画出来。这里我们可以拆分一下,两个矩形,两个圆形,两个反圆角,也就是两个线性渐变,4个径向渐变,如下代码所示。tab-item{padding:10px35px;背景图像:径向渐变(圆圈在00,透明15px,蓝色0),径向渐变(圆圈在00,透明15px,蓝色0),径向渐变(圆圈在00,绿色12px,透明0,径向渐变(圆形12px0,绿色12px,透明0,线性渐变(红色,红色),线性渐变(红色,红色);背景重复:不重复;背景位置:15px顶部,右侧15pxtop0,leftbottom,rightbottom,centerbottom,center,bootom;background-size:30px30px,30px30px,12px12px,12px12px,calc(100%-30px)calc(100%-12px),calc(100%-54px)100%;}虽然实现了,但是很啰嗦,仔细观察发现两个圆是可以平铺实现的,两个反圆角可以看成一个半圆,然后就可以了tab-item{position:relative;padding:10px35px;cursor:pointer;background-image:radial-gradient(circleat15px0,transparent15px,blue0),radial-gradientt(圆圈在27px12px,绿色12px,透明0),线性渐变(红色,红色),线性渐变(红色,红色);背景大小:100%15px,calc(100%-54px),calc(100%-30px)calc(100%-12px),calc(100%-54px)100%;background-position:-15pxbottom,lefttop,centerbottom,centerbottom;background-repeat:repeat-x,repeat-x,no-repeat,no-repeat;}最终实时效果如下(以上为示意图)完成代码可以访问chrome-tab-gradient(codepen.io)3.自适应svg渐变虽然万能,但是代码量很多,很考验耐心。对于这个例子,svg也是一个很好的解决方案。中间的圆角矩形比较简单,直接用rect两边的反圆角可以直接用path路径(可以用各种绘图软件生成)然后用这3段svg代码作为背景,可以用background-size和background-position来调整和控制。tab-item{position:relative;填充:10px35px;边距:0-15px;游标:指针;过渡:.2s;background-image:url("data:image/svg+xml,%3Csvgwidth='100'height='100'viewBox='00100100'fill='none'xmlns='http://www.w3.org/2000/svg'%3E%3Cpathfill-rule='evenodd'clip-rule='evenodd'd='M100100C44.772100055.22800v100h100z'fill='%23F8EAE7'/%3E%3C/svg%3E"),url("data:image/svg+xml,%3Csvgwidth='100'height='100'viewBox='00100100'fill='none'xmlns='http://www.w3.org/2000/svg'%3E%3Cpathfill-rule='evenodd'clip-rule='evenodd'd='M0100c55.2280100-44.772100-100v100H0z'fill='%23F8EAE7'/%3E%3C/svg%3E"),url("data:image/svg+xml,");background-size:12px12px,12px12px,calc(100%-24px)calc(100%+12px);background-position:rightbottom,leftbottom,centertop;background-repeat:no-repeat;}实时效果如下完整代码可以在chrome-tab-svg中访问(codepen.io)另外可能有人会疑惑,这里为什么用3段svg?用1段svg包含3个路径不就可以了吗?答案是否定的没有办法在svg中灵活使用定位。比如要实现右下角的定位,svg只能用100%,不能用calc(100%-12px),更何况CSS有右下角等定位属性,所以必须用CSS实现多背景4.以上画框的方法还是太复杂了。你能“切图”吗?当然也是可以的,但是也需要一定的技巧来实现自适应。这可以使用CSS3border-image来实现。border-image可以参考这篇文章:JELLY|正确使用border-image(jd.com)。准备这样一张图片就可以了,svg或者png都可以。svg如下然后按照border-image规范切代码实现如下,记得加上border.tab-item{position:relative;填充:08px;边距:0-15px;游标:指针;边框宽度:12px27px15px;边框样式:实心;border-image:url("data:image/svg+xml,%3Csvgwidth='67'height='33'viewBox='006733'fill='none'xmlns='http://www.w3.org/2000/svg'%3E%3Cpathfill-rule='evenodd'clip-rule='evenodd'd='M270c-6.6270-125.373-1212v6c08.284-6.71615-1515h67c-8.2840-15-6.716-15-15v-6c0-6.627-5.373-12-12-12H27z'fill='%23F8EAE7'/%3E%3C/svg%3E")122715fill;}实时效果如下完整代码可以在chrome-tab-border-image(codepen.io)中查看,虽然代码实现比较简单,但是因为加了边框,内容大小有些难以控制。5.面膜之前的背景图遮罩的方法其实是有问题的。颜色都在背景图片中,几乎是固定的,不方便修改。那么,借助mask遮蔽,这个问题就可以轻松解决有了之前的背景(gradient或者svg都可以),只需要将背景批量替换成-webkit-mask就可以了,以svg为例,替换后如下。tab-item{位置:相对;填充:10px35px;游标:指针;背景:#F8EAE7;-webkit-mask-image:url("data:image/svg+xml,%3Csvgwidth='100'height='100'viewBox='00100100'fill='none'xmlns='http://www.w3.org/2000/svg'%3E%3Cpathfill-rule='evenodd'clip-rule='evenodd'd='M100100C44.772100055.22800v100h100z'fill='%23F8EAE7'/%3E%3C/svg%3E"),url("data:image/svg+xml,%3Csvgwidth='100'height='100'viewBox='00100100'fill='none'xmlns='http://www.w3.org/2000/svg'%3E%3Cpathfill-rule='evenodd'clip-rule='evenodd'd='M0100c55.2280100-44.772100-100v100H0z'fill='%23F8EAE7'/%3E%3C/svg%3E"),url("data:image/svg+xml,");-webkit-mask-size:12px12px,12px12px,calc(100%-24px)calc(100%+12px);-webkit-掩码位置:右下、左下、中上;-webkit-mask-repeat:no-repeat;}现在可以方便的控制背景颜色,如果需要改变背景颜色,直接改就可以了。tab-item:hover{background:#F2D0CA;}完成代码可以在chrome-tab-mask(codepen.io)中找到。另外,喜欢“切图”的还可以使用mask-border,和上面的border-image基本一样,但是mask的效果还是用这张图,切图代码实现是.tab-item{/*...*/-webkit-mask-box-image:url("data:image/svg+xml,%3Csvgwidth='67'height='33'viewBox='006733'fill='none'xmlns='http://www.w3.org/2000/svg'%3E%3Cpathfill-rule='evenodd'clip-rule='evenodd'd='M270c-6.6270-125.373-1212v6c08.284-6.71615-1515h67c-8.2840-15-6.716-15-15v-6c0-6.627-5.373-12-12-12H27z'fill='%23F8EAE7'/%3E%3C/svg%3E")122715;}完整代码可以访问chrome-tab-mask-border(codepen.io)还在草稿中,有一个替代属性-webkit-mask-box-image可以使用6.总结和解释上面介绍了5种不同的布局方式,下面总结一下实现要点:border-radius和clip-path可以实现凹圆渐变。background-repeat补全svg中的rect可以实现自适应圆角矩形,作为背景也适用。可以使用多段svg作为多背景,分别控制大小和位置。border-image可以实现自适应效果,需要注意设置border-widthmaskmask可以直接使用gradient或者svg作为mask层,就可以修改背景颜色更方便mask-border和border-image的用法类似,但是目前只有-webkit-内核支持,各有各的特点,比如渐变无所不能,但是实现起来最麻烦,svg是简单,但也有局限性(中间的圆角矩形,不支持其他形状),主要是拓展思路,大家可以根据实际需要选择,下次遇到其他布局,也可以从这些方面考虑方面最后,如果你觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发???