CSS 实现Chrome标签栏的技巧


Posted in HTML / CSS onAugust 04, 2021

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

CSS 实现Chrome标签栏的技巧

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

一、伪元素拼接

假设有这样一个 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>

首先可以考虑的一种方式就利用两个伪元素拼接

CSS 实现Chrome标签栏的技巧

中间的圆角比较容易,左右两边的反向圆角如何实现呢?其实可以想想有哪些可以实现圆形的样式,这里想到了border-radius ,可以这样来实现

  • 画一个透明的圆
  • 给圆加上足够大的边框或者投影
  • 裁剪一小部分
  • 完成

示意如下

CSS 实现Chrome标签栏的技巧

用代码实现就是

.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);
}

最终实时效果如下

CSS 实现Chrome标签栏的技巧

这里裁剪是用 clip-path 实现的,注意左右可以朝里面多裁剪一点,以免拼接出现缝隙,完成代码可访问 chrome-tab (codepen.io)

当然这里的反向圆角还可以采用径向渐变来实现,接着往下看。

二、万能的渐变

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

CSS 实现Chrome标签栏的技巧

用代码实现就是

.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%;
}

虽然实现了,但是非常啰嗦,仔细观察发现,两个圆形是可以利用平铺实现的,两个反向圆角可以看成是一个半圆,然后也可以平铺,示意如下

CSS 实现Chrome标签栏的技巧

这样,只需要两个径向渐变就可以实现了,代码如下

.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;
}

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

CSS 实现Chrome标签栏的技巧

完成代码可访问 chrome-tab-gradient (codepen.io)

三、自适应的svg

渐变虽然是万能的,但是代码量比较多,非常考验耐心。对于这个例子,svg 也是不错的方案。

CSS 实现Chrome标签栏的技巧

中间的圆角矩形比较容易,用 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-size 和 background-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;
}

实时效果如下

CSS 实现Chrome标签栏的技巧

完整代码可以访问 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 都行

CSS 实现Chrome标签栏的技巧

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 规范进行切割就行了

CSS 实现Chrome标签栏的技巧

代码实现如下,记得要加上 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;
}

实时效果如下

CSS 实现Chrome标签栏的技巧

完整代码可以访问 chrome-tab-border-image (codepen.io)

虽然代码实现比较简介,但是由于要加上 border,导致内容尺寸有些不好控制

五、mask 遮罩

前面几种背景图片的方式,其实有一个问题,颜色都在背景图片中,几乎是固定的,不方便修改,那么,借助 mask 遮罩,可以很轻松的解决这个问题。

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

CSS 实现Chrome标签栏的技巧

以 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 基本一致,只不过得到了遮罩的效果

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

CSS 实现Chrome标签栏的技巧

代码实现就是

.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;
}

CSS 实现Chrome标签栏的技巧

完整代码可以访问 chrome-tab-mask-border (codepen.io)

目前仍然在草案当中,有一个替代属性-webkit-mask-box-image 可以使用

六、总结和说明

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

  1. border-radius 配合 clip-path 可以实现内凹圆角
  2. 渐变是万能的,重复的内容尽量通过 background-repeat 来完成
  3. svg 中 rect 可以实现自适应圆角矩形,作为背景同样适用
  4. 可以将多段 svg 作为多背景,分别控制尺寸和位置
  5. border-image 可以实现自适应效果,需要注意设置 border-width
  6. mask 遮罩可以直接使用渐变或者svg作为遮罩层,可以更方便的修改背景色
  7. mask-border 和 border-image 使用类似,不过目前只有 -webkit- 内核支持

到此这篇关于CSS 实现Chrome标签栏的技巧的文章就介绍到这了,更多相关CSS Chrome标签栏内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

 
HTML / CSS 相关文章推荐
利用css3实现的简单的鼠标悬停按钮
Nov 04 HTML / CSS
CSS3实现千变万化的文字阴影text-shadow效果设计
Apr 26 HTML / CSS
使用CSS3中的calc()属性来以算式表达尺寸数值
Jun 06 HTML / CSS
CSS3实现3D翻书效果
Jun 20 HTML / CSS
HTML5 video 视频标签使用介绍
Feb 03 HTML / CSS
HTML5有哪些新特征
Dec 01 HTML / CSS
详解HTML5 window.postMessage与跨域
May 11 HTML / CSS
html5实现图片转圈的动画效果——让页面动起来
Oct 16 HTML / CSS
移动端Html5页面生成图片解决方案
Aug 07 HTML / CSS
HTML5 video 上传预览图片视频如何设置、预览视频某秒的海报帧
Aug 28 HTML / CSS
div或img图片高度随宽度自适应的方法
Feb 06 HTML / CSS
CSS完成视差滚动效果
Apr 27 HTML / CSS
纯html+css实现Element loading效果
纯html+css实现奥运五环的示例代码
HTML+CSS实现导航条下拉菜单的示例代码
Aug 02 #HTML / CSS
CSS实现两列布局的N种方法
Aug 02 #HTML / CSS
html+css实现滚动到元素位置显示加载动画效果
Aug 02 #HTML / CSS
纯html+css实现打字效果
html form表单基础入门案例讲解
Jul 21 #HTML / CSS
You might like
PHP多线程抓取网页实现代码
2010/07/22 PHP
php skymvc 一款轻量、简单的php
2011/06/28 PHP
php ctype函数中文翻译和示例
2014/03/21 PHP
php使用文本统计访问量的方法
2016/05/12 PHP
PHP实现Redis单据锁以及防止并发重复写入
2018/04/10 PHP
laravel中数据显示方法(默认值和下拉option默认选中)
2019/10/11 PHP
Bookmarklet实现启动jQuery(模仿 云输入法)
2010/09/15 Javascript
《JavaScript高级程序设计》阅读笔记(三) ECMAScript中的引用类型
2012/02/27 Javascript
JS获取IP、MAC和主机名的五种方法
2013/11/14 Javascript
Egret引擎开发指南之创建项目
2014/09/03 Javascript
JavaScript设计模式之单例模式实例
2014/09/24 Javascript
15个非常实用的JavaScript代码片段
2016/12/18 Javascript
基于jQuery实现的单行公告活动轮播效果
2017/08/23 jQuery
微信小程序实现bindtap等事件传参
2019/04/08 Javascript
JS如何实现在弹出窗口中加载页面
2020/12/03 Javascript
JS实现选项卡插件的两种写法(jQuery和class)
2020/12/30 jQuery
[01:10:48]完美世界DOTA2联赛PWL S2 GXR vs PXG 第一场 11.18
2020/11/18 DOTA
详细解读Python中的__init__()方法
2015/05/02 Python
利用Django内置的认证视图实现用户密码重置功能详解
2017/11/24 Python
一道python走迷宫算法题
2018/01/22 Python
python如何通过实例方法名字调用方法
2018/03/21 Python
Python实现的生产者、消费者问题完整实例
2018/05/30 Python
python基础学习之如何对元组各个元素进行命名详解
2018/07/12 Python
Python爬虫框架scrapy实现downloader_middleware设置proxy代理功能示例
2018/08/04 Python
解决nohup执行python程序log文件写入不及时的问题
2019/01/14 Python
python生成大写32位uuid代码
2020/03/03 Python
英国健身仓库:Bodybuilding Warehouse
2019/03/06 全球购物
大专自我鉴定范文
2013/10/01 职场文书
校园安全教育广播稿
2014/02/17 职场文书
优秀员工获奖感言
2014/03/01 职场文书
社区母亲节活动记录
2014/03/06 职场文书
幼师求职自荐信
2014/05/31 职场文书
2015年世界无烟日活动方案
2015/05/04 职场文书
大学体育课感想
2015/08/10 职场文书
使用css样式设计一个简单的html登陆界面的实现
2021/03/30 HTML / CSS
MySQL transaction事务安全示例讲解
2022/06/21 MySQL