京东6.18大促主会场领京享红包更优惠

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 4079|回复: 0

CSS 实现Chrome标签栏的技巧

[复制链接]

31

主题

0

回帖

10

积分

新手上路

积分
10
发表于 2021-11-21 02:17:08 | 显示全部楼层 |阅读模式 来自 中国
这次来看一个带特殊圆角导航栏布局,如下谷歌浏览器的标签栏:2 V6 j+ D+ T. g+ {

4 u8 L4 C& n5 H0 [0 d! l- H这样一个布局如何实现呢?下面介绍几种方法( T+ a. L. C; U" a/ r
一、伪元素拼接) ~3 S7 J) [5 e! A6 X* y
" ~8 D1 j" @( H- @$ f! V/ U4 a# q
假设有这样一个 HTML 结构
  1.   [url=https://mxzdjyxk.cn/]Svelte API[/url]  [url=https://mxzdjyxk.cn/]Svelte API[/url]  [url=https://mxzdjyxk.cn/]Svelte API[/url]  [url=https://mxzdjyxk.cn/]Svelte API[/url]
复制代码
首先可以考虑的一种方式就利用两个伪元素拼接
4 Y# \) ^' R$ }% F/ ~
. j6 F0 x4 Z5 [6 H
中间的圆角比较容易,左右两边的反向圆角如何实现呢?其实可以想想有哪些可以实现圆形的样式,这里想到了border-radius ,可以这样来实现
. L( O# \6 a1 W' h' z# p& e
       
    0 H) j( y& H& G( C. g' O% `/ A, N
  • 画一个透明的圆    & c- S3 G5 g. p/ \" O) d
  • 给圆加上足够大的边框或者投影   
    ' Y; M  e7 D' u) _% r
  • 裁剪一小部分    ! S& |1 b" ^! e- _. C: h2 k- ?
  • 完成. V3 s; t5 Q- C$ E
示意如下1 F# L$ `: i% [! v+ r" ~2 N. p

, l( h4 r# w1 @4 z' K用代码实现就是
  1. .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);}
复制代码
最终实时效果如下
/ t) d4 V3 i' j

3 X( z* f# T) l6 x. E  {这里裁剪是用 clip-path 实现的,注意左右可以朝里面多裁剪一点,以免拼接出现缝隙,完成代码可访问 chrome-tab (codepen.io)& Q5 Y1 k0 y/ ~, `& ~
当然这里的反向圆角还可以采用径向渐变来实现,接着往下看。* n- n1 r! ]* E; C. |; ]+ Y% A
二、万能的渐变
5 q* Y+ y2 W$ H* I, s/ N4 c" zCSS 渐变几乎是无所不能的,什么的图形都能绘制,这里可以拆分一下,两个矩形,两个圆形,还有两个反向圆角,也就是 2 个 线性渐变,4 个径向渐变,示意如下2 O7 [6 I5 }! X7 o+ w$ e6 }+ p
2 F+ q( d$ {+ a7 _( \$ j
用代码实现就是
  1. .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%;}
复制代码
虽然实现了,但是非常拢邢腹鄄旆⑾郑礁鲈残问强梢岳闷狡淌迪值模礁龇聪蛟步强梢钥闯墒且桓霭朐玻缓笠部梢云狡蹋疽馊缦/p>

8 M) E! z) p/ k/ j& P+ J- N! j这样,只需要两个径向渐变就可以实现了,代码如下
  1. .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;}
复制代码
最终实时效果如下(上面是原理图). F6 H5 |1 ]  y; Z* X- H
' v+ u# K) H; U$ @+ B& h
完成代码可访问 chrome-tab-gradient (codepen.io)
' _$ N. x3 U# N' q6 G6 ^& K2 S' I三、自适应的svg: J& q4 L" E" u

, o; B0 x7 t, e" P: E  T, u渐变虽然是万能的,但是代码量比较多,非常考验耐心。对于这个例子,svg 也是不错的方案。
1 O1 O4 Y( U9 Z- I8 J. d. `

+ s8 k  w; T' ^+ a& b1 Z% D+ z中间的圆角矩形比较容易,用 rect 就行
  1.           
复制代码
两边的反向圆角可以直接使用一段 path 路径(各种图形软件都可以生成)
  1.        
复制代码
  1.        
复制代码
然后把这 3 段 svg 代码作为背景就可以了,可以用 background-size 和 background-position 进行调整和控制
  1. .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,");  background-size: 12px 12px, 12px 12px, calc(100% - 24px) calc(100% + 12px);  background-position: right bottom, left bottom, center top;  background-repeat: no-repeat;}
复制代码
实时效果如下
# Y2 B# n4 `3 I" N0 d0 |( e

' W# M" H; q2 H$ G) f% a$ Y6 _* K完整代码可以访问 chrome-tab-svg (codepen.io)( E% W: U. L1 T( c
另外,有人可能会奇怪,这里**为什么要用3段 svg?用 1 段 svg 里面包含 3 个路径不行吗?**答案是不行的。svg 里没法灵活使用定位,比如要实现位于右下角,svg 只能使用 100% 而不能使用 calc( 100% - 12px ),更别说 CSS 还有 right bottom 这样的定位属性了,所以必须采用 CSS多背景 实现" [. W& \( t! b6 T
四、图片边框# c  Q/ h2 C; |4 ?' g" u! e6 D

4 D2 |! A0 e6 n% g3 B上面几种方式还是觉得太复杂了,能不能**“切图”**呢?当然也是可以的,不过也需要一定的技巧,这样才能实现自适应。这里可以采用 CSS3 border-image 来实现。关于 border-image 可以参考这篇文章:JELLY | border-image 的正确用法 (jd.com)。
) {% B2 d4 X* H& S准备这样一张图就可以了,svg 或者 png 都行0 P- u7 B3 S: c! v7 k

3 N! `1 p) M" e8 }9 @svg 如下
  1.   
复制代码
接着根据 border-image 规范进行切割就行了. w' H; M( |  ?6 ~7 \) n" N

0 d* V! q9 l% n" Z  c* ^代码实现如下,记得要加上 border
  1. .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;}
复制代码
实时效果如下
5 `. ^! F9 ~  c" @* r/ f( \5 P2 D

+ E2 {4 D. t# e5 K  d' f. v) I, G完整代码可以访问 chrome-tab-border-image (codepen.io)
1 b; `$ B: V& e$ T" `6 \. E; h虽然代码实现比较简介,但是由于要加上 border,导致内容尺寸有些不好控制
9 h5 w7 q# Z* o+ J3 I. W五、mask 遮罩
4 z; c6 P" L. C3 @$ k( [: f# R$ W" P/ i
前面几种背景图片的方式,其实有一个问题,颜色都在背景图片中,几乎是固定的,不方便修改,那么,借助 mask 遮罩,可以很轻松的解决这个问题。
' U2 W% |- |; j$ |5 n) N有了前面的背景(渐变或者svg都行),只需要把 background 批量换成 -webkit-mask 就行了,就像这样
' \# P2 R8 b! ^( |7 _( h9 L

6 z( T7 Z* w7 t$ a; t. m1 Q4 r以 svg 为例,替换以后如下
  1. .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,");  -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;}
复制代码
现在控制背景颜色就方便了,如果需要改变背景色,直接改变就行了
  1. .tab-item:hover{  background: #F2D0CA;}
复制代码
完整代码可以查看 chrome-tab-mask (codepen.io)
' \% ^. e3 F4 n( K另外,喜欢**“切图”**的还可以使用 mask-border 实现,和上面的 border-image 基本一致,只不过得到了遮罩的效果
9 O/ I4 d% r% d" ~. {0 H还是采用这张图,进行切割3 ]% ~4 ^" z, T; l+ v9 s
+ K# b; a6 A! E2 B+ M3 B. d
代码实现就是
  1. .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;}
复制代码

! `/ X: h8 y) U; l2 v2 s完整代码可以访问 chrome-tab-mask-border (codepen.io)
- {8 E* o/ H& V. m目前仍然在草案当中,有一个替代属性-webkit-mask-box-image 可以使用
0 c/ u, O  h" m9 ?3 V" v六、总结和说明; b: F( c8 N- ^( @! @6 F
9 j- T; x7 Q. N
以上共介绍了 5 种不同的布局方式,下面总结一下实现要点:$ W& A! _2 L0 ?+ l2 |
        " Y/ k" z& B; b; V/ l' J
  • border-radius 配合 clip-path 可以实现内凹圆角   
    . Y$ J0 y9 H6 J
  • 渐变是万能的,重复的内容尽量通过 background-repeat 来完成    3 L$ C. _9 g7 `7 `* h' T+ L
  • svg 中 rect 可以实现自适应圆角矩形,作为背景同样适用   
    0 f  m7 i! E; o# S: k
  • 可以将多段 svg 作为多背景,分别控制尺寸和位置    / G/ f# a/ S: h8 o2 p
  • border-image 可以实现自适应效果,需要注意设置 border-width    + d. j2 I) r% y1 \3 X; J/ H
  • mask 遮罩可以直接使用渐变或者svg作为遮罩层,可以更方便的修改背景色   
    0 Z" i! M, x6 w. E1 [
  • mask-border 和 border-image 使用类似,不过目前只有 -webkit- 内核支持/ Q% j9 O+ _; R
到此这篇关于CSS 实现Chrome标签栏的技巧的文章就介绍到这了,更多相关CSS Chrome标签栏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!, p2 T7 ?/ g5 J  T6 e  i, O6 D7 H
* \! l* N0 p; L2 p
来源:http://www.jb51.net/css/784321.html  C$ [3 w. T  H4 m- z
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×

帖子地址: 

梦想之都-俊月星空 优酷自频道欢迎您 http://i.youku.com/zhaojun917
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|梦想之都-俊月星空 ( 粤ICP备18056059号 )|网站地图

GMT+8, 2026-6-22 23:06 , Processed in 0.039217 second(s), 24 queries .

Powered by Mxzdjyxk! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表