这次来看一个带非凡圆角导航栏布局,如下谷歌浏览器的标签栏:

这样一个布局如何实现呢?上面介绍几种办法

一、伪元素拼接

假如有这样一个 HTML 构造

<nav class="tab">  <a class="tab-item">Svelte API</a>  <a class="tab-item active">Svelte API</a>  <a class="tab-item">Svelte API</a>  <a class="tab-item">Svelte API</a></nav>

首先能够思考的一种形式就利用两个伪元素拼接

两头的圆角比拟容易,左右两边的反向圆角如何实现呢?其实能够想想有哪些能够实现圆形的款式,这里想到了border-radius ,能够这样来实现

  1. 画一个通明的圆
  2. 给圆加上足够大的边框或者投影
  3. 裁剪一小部分
  4. 实现

示意如下是

用代码实现就是

.tab-item{  position: relative;  background-color: red;  padding: 10px 15px;  border-radius: 12px 12px 0 0;  cursor: pointer;  transition: .2s;}.tab-item::before,.tab-item::after{  position: absolute;  bottom: 0;  content: '';  width: 20px;  height: 20px;  border-radius: 100%;  box-shadow: 0 0 0 40px red;/*应用box-shadow不影响尺寸*/  transition: .2s;}.tab-item::before{  left: -20px;  clip-path: inset(50% -10px 0 50%);}.tab-item::after{  right: -20px;  clip-path: inset(50% 50% 0 -10px);}

最终实时成果如下

这里裁剪是用 clip-path 实现的,留神左右能够朝外面多裁剪一点,免得拼接呈现缝隙,实现代码可拜访 chrome-tab (codepen.io)

当然这里的反向圆角还能够采纳径向突变来实现,接着往下看。

二、万能的突变

CSS 突变简直是无所不能的,什么的图形都能绘制,这里能够拆分一下,两个矩形,两个圆形,还有两个反向圆角,也就是 2 个 线性突变,4 个径向突变,示意如下

用代码实现就是

.tab-item{  padding: 10px 35px;  background-image:     radial-gradient(circle at 0 0, transparent 15px,blue 0),    radial-gradient(circle at 0 0, transparent 15px,blue 0),    radial-gradient(circle at 0 0, green 12px,transparent 0,    radial-gradient(circle at 12px 0, green 12px,transparent 0,    linear-gradient(red,red),    linear-gradient(red,red);  background-repeat: no-repeat;  background-position: 15px top, right 15px top 0, left bottom, right bottom, center bottom, center, bootom;  background-size: 30px 30px, 30px 30px, 12px 12px, 12px 12px, calc(100% - 30px) calc(100% - 12px), calc(100% - 54px) 100%;}

尽管实现了,然而十分啰嗦,仔细观察发现,两个圆形是能够利用平铺实现的,两个反向圆角能够看成是一个半圆,而后也能够平铺,示意如下

这样,只须要两个径向突变就能够实现了,代码如下

.tab-item{  position: relative;  padding: 10px 35px;  cursor: pointer;  background-image: radial-gradient(circle at 15px 0, transparent 15px,blue 0),    radial-gradient(circle at 27px 12px, green 12px,transparent 0),    linear-gradient(red,red),    linear-gradient(red,red);  background-size: 100% 15px,calc(100% - 54px), calc(100% - 30px) calc(100% - 12px), calc(100% - 54px) 100%;  background-position: -15px bottom, left top, center bottom, center bottom;  background-repeat: repeat-x, repeat-x, no-repeat, no-repeat;}

最终实时成果如下(下面是原理图)

实现代码可拜访 chrome-tab-gradient (codepen.io)

三、自适应的svg

突变尽管是万能的,然而代码量比拟多,十分考验急躁。对于这个例子,svg 也是不错的计划。

两头的圆角矩形比拟容易,用 rect 就行

<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%'>       <rect rx="12" width='100%' height='100%' fill="#3A8EFF"/></svg>

两边的反向圆角能够间接应用一段 path 门路(各种图形软件都能够生成)

<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">    <path fill-rule="evenodd" clip-rule="evenodd" d="M0 100C55.2285 100 100 55.2285 100 0V100H0Z" fill="#3A8EFF"/></svg>
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">    <path fill-rule="evenodd" clip-rule="evenodd" d="M100 100C44.7715 100 0 55.2285 0 0V100H100Z" fill="#3A8EFF"/></svg>

而后把这 3 段 svg 代码作为背景就能够了,能够用 background-sizebackground-position 进行调整和管制

.tab-item{  position: relative;  padding: 10px 35px;    margin: 0 -15px;  cursor: pointer;  transition: .2s;  background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M100 100C44.772 100 0 55.228 0 0v100h100z' fill='%23F8EAE7'/%3E%3C/svg%3E"),    url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 100c55.228 0 100-44.772 100-100v100H0z' fill='%23F8EAE7'/%3E%3C/svg%3E"),    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><rect rx='12' width='100%' height='100%' fill='%23F8EAE7'/></svg>");  background-size: 12px 12px, 12px 12px, calc(100% - 24px) calc(100% + 12px);  background-position: right bottom, left bottom, center top;  background-repeat: no-repeat;}

实时成果如下

残缺代码能够拜访 chrome-tab-svg (codepen.io)

另外,有人可能会奇怪,这里为什么要用3段 svg?用 1 段 svg 外面蕴含 3 个门路不行吗?答案是不行的。svg 里没法灵便应用定位,比方要实现位于右下角,svg 只能应用 100% 而不能应用 calc( 100% - 12px ),更别说 CSS 还有 right bottom 这样的定位属性了,所以必须采纳 CSS多背景 实现

四、图片边框

下面几种形式还是感觉太简单了,能不能“切图”呢?当然也是能够的,不过也须要肯定的技巧,这样能力实现自适应。这里能够采纳 CSS3 border-image 来实现。对于 border-image 能够参考这篇文章:JELLY | border-image 的正确用法 (jd.com)。

筹备这样一张图就能够了,svg 或者 png 都行

svg 如下

<svg width="67" height="33" viewBox="0 0 67 33" fill="none" xmlns="http://www.w3.org/2000/svg">  <path fill-rule="evenodd" clip-rule="evenodd" d="M27 0c-6.627 0-12 5.373-12 12v6c0 8.284-6.716 15-15 15h67c-8.284 0-15-6.716-15-15v-6c0-6.627-5.373-12-12-12H27z" fill="#F8EAE7"/></svg>

接着依据 border-image 标准进行切割就行了

代码实现如下,记得要加上 border

.tab-item{  position: relative;  padding: 0 8px;  margin: 0 -15px;  cursor: pointer;  border-width: 12px 27px 15px;  border-style: solid;  border-image: url("data:image/svg+xml,%3Csvg width='67' height='33' viewBox='0 0 67 33' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M27 0c-6.627 0-12 5.373-12 12v6c0 8.284-6.716 15-15 15h67c-8.284 0-15-6.716-15-15v-6c0-6.627-5.373-12-12-12H27z' fill='%23F8EAE7'/%3E%3C/svg%3E") 12 27 15 fill;}

实时成果如下

残缺代码能够拜访 chrome-tab-border-image (codepen.io)

尽管代码实现比拟简介,然而因为要加上 border,导致内容尺寸有些不好管制

五、mask 遮罩

后面几种背景图片的形式,其实有一个问题,色彩都在背景图片中,简直是固定的,不不便批改,那么,借助 mask 遮罩,能够很轻松的解决这个问题。

有了后面的背景(突变或者svg都行),只须要把 background 批量换成 -webkit-mask 就行了,就像这样

以 svg 为例,替换当前如下

.tab-item{  position: relative;  padding: 10px 35px;  cursor: pointer;  background: #F8EAE7;  -webkit-mask-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M100 100C44.772 100 0 55.228 0 0v100h100z' fill='%23F8EAE7'/%3E%3C/svg%3E"),    url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 100c55.228 0 100-44.772 100-100v100H0z' fill='%23F8EAE7'/%3E%3C/svg%3E"),    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><rect rx='12' width='100%' height='100%' fill='%23F8EAE7'/></svg>");  -webkit-mask-size: 12px 12px, 12px 12px, calc(100% - 24px) calc(100% + 12px);  -webkit-mask-position: right bottom, left bottom, center top;  -webkit-mask-repeat: no-repeat;}

当初管制背景色彩就不便了,如果须要扭转背景色,间接扭转就行了

.tab-item:hover{  background: #F2D0CA;}

残缺代码能够查看 chrome-tab-mask (codepen.io)

另外,喜爱“切图”的还能够应用 mask-border 实现,和下面的 border-image 基本一致,只不过失去了遮罩的成果

还是采纳这张图,进行切割

代码实现就是

.tab-item{  /*...*/  -webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='67' height='33' viewBox='0 0 67 33' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M27 0c-6.627 0-12 5.373-12 12v6c0 8.284-6.716 15-15 15h67c-8.284 0-15-6.716-15-15v-6c0-6.627-5.373-12-12-12H27z' fill='%23F8EAE7'/%3E%3C/svg%3E") 12 27 15;}

残缺代码能够拜访 chrome-tab-mask-border (codepen.io)

目前依然在草案当中,有一个代替属性 -webkit-mask-box-image 能够应用

六、总结和阐明

以上共介绍了 5 种不同的布局形式,上面总结一下实现要点:

  1. border-radius 配合 clip-path 能够实现内凹圆角
  2. 突变是万能的,反复的内容尽量通过 background-repeat 来实现
  3. svgrect 能够实现自适应圆角矩形,作为背景同样实用
  4. 能够将多段 svg 作为多背景,别离管制尺寸和地位
  5. border-image 能够实现自适应成果,须要留神设置 border-width
  6. mask 遮罩能够间接应用突变或者svg作为遮罩层,能够更不便的批改背景色
  7. mask-borderborder-image 应用相似,不过目前只有 -webkit- 内核反对

各有各的特点,比方突变是万能的,然而实现最为繁琐,svg 尽管简略,然而也有局限性(两头的圆角矩形,其余形态就不反对了) ,次要是开辟思维,大家能够依据理论需要自行抉择,下次碰到其余布局也能够从这几个方面来思考。最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤