• <button id="eiyoe"><acronym id="eiyoe"></acronym></button>
    <em id="eiyoe"></em>

  • <rp id="eiyoe"><acronym id="eiyoe"><input id="eiyoe"></input></acronym></rp>
      查看: 2854|回復: 0
      上一主題 下一主題

      CSS 實現Chrome標簽欄的技巧

      80572

      主題

      0

      好友

      積分

      離線 發信

      跳轉到指定樓層
      樓主
      發表于 2021-11-21 02:07 | 只看該作者 | 倒序瀏覽

      這次來看一個帶特殊圓角導航欄布局,如下谷歌瀏覽器的標簽欄:

      這樣一個布局如何實現呢?下面介紹幾種方法

      一、偽元素拼接

      假設有這樣一個 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 ,可以這樣來實現

      • 畫一個透明的圓
      • 給圓加上足夠大的邊框或者投影
      • 裁剪一小部分
      • 完成

      示意如下

      用代碼實現就是

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

      雖然實現了,但是非常攏邢腹鄄旆⑾鄭礁鱸殘問強梢岳悶狡淌迪值模礁齜聰蛟步強梢鑰闖墑且桓靄朐玻緩笠部梢云狡蹋疽餿縵/p>

      這樣,只需要兩個徑向漸變就可以實現了,代碼如下

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

      實時效果如下

      完整代碼可以訪問 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. svg 中 rect 可以實現自適應圓角矩形,作為背景同樣適用
      4. 可以將多段 svg 作為多背景,分別控制尺寸和位置
      5. border-image 可以實現自適應效果,需要注意設置 border-width
      6. mask 遮罩可以直接使用漸變或者svg作為遮罩層,可以更方便的修改背景色
      7. mask-border 和 border-image 使用類似,不過目前只有 -webkit- 內核支持

      到此這篇關于CSS 實現Chrome標簽欄的技巧的文章就介紹到這了,更多相關CSS Chrome標簽欄內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章,希望大家以后多多支持腳本之家!

      來源:http://www.jb51.net/css/784321.html