中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

CSS如何實現漸變提示框

發布時間:2021-07-13 17:55:41 來源:億速云 閱讀:132 作者:chen 欄目:web開發

這篇文章主要講解了“CSS如何實現漸變提示框”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“CSS如何實現漸變提示框”吧!

今天來看一種十分常見的交互:提示框(tooltips)。通常提示框都是純色的,比如下面這個

CSS如何實現漸變提示框

這類布局實現還不算復雜,可以用一個圓角矩形和一個小三角拼接形成,設置相同的顏色就可以了

CSS如何實現漸變提示框

這個并不是本文的重點,有興趣的可以訪問 css-tips (codepen.io)

https://codepen.io/xboxyan/pen/MLJjWQ

有時候,為了突出強調產品的特點或者為了跟隨設計的潮流,設計會用上漸變背景,比如 lulu UI Edge 版本中的 Tips 組件

CSS如何實現漸變提示框

如果仍然采用“拼接”的方式,不可避免會出現銜接不上的問題,有明顯的“割裂”感,視覺還原會大打折扣

CSS如何實現漸變提示框

那么,如何實現這類效果呢?一起來看看吧

一、clip-path 裁剪

clip-path 可能是很多人馬上就能想到的方式。但是實際操作下來,還是會遇到很多麻煩

  • clip-path: path 可以支持任意形狀,但是卻沒法實現自適應寬高

  • clip-path: polygon 可以實現小尖角,但是無法實現圓角

  • clip-path: inset 可以實現自適應圓角矩形,但是無法實現下方的小尖角

如何解決這個問題呢?其實把 2 和 3 結合起來就可以了

這里需要兩個相同大小的容器,可以用 ::before::after 來代替,然后設置相同的背景色,可以通過自定義屬性定義

.tips{
   position: relative;
   --bg: linear-gradient(45deg, #ff3c41, #ff9800);
}
.tips::before,.tips::after{
  content:'';
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  background: var(--bg);/*完全相同的背景*/
  z-index: -1;
}

為什么要用兩個相同大小的容器呢? 這是為了保證接下來漸變背景在裁剪時完全吻合

CSS如何實現漸變提示框

接著其中一個裁剪成圓角矩形,另外一個裁剪成小三角,然后重疊起來就可以了

.tips::before{
  clip-path: inset(0 0 5px 0 round 5px);
  /*round 可以設置圓角*/
}
.tips::after{
  clip-path: polygon(calc(50% - 5px) calc(100% - 5px), calc(50% + 5px) calc(100% - 5px), 50% 100%);
  /* 實現小三角,只需要3個點的坐標就可以了 */
}

可以看到提示框完全是自適應的,實時效果如下

CSS如何實現漸變提示框

完整代碼可訪問 tooltips-clip-path (codepen.io)

https://codepen.io/xboxyan/pen/ExWLyKR

二、mask 遮罩

除了 clip-pathmask 也是一種思路。如果還不熟悉 mask,可以參考這一篇

奇妙的 CSS MASK (juejin.im)

https://juejin.cn/post/6846687594693001223

這里的原理如下

CSS如何實現漸變提示框

利用 mask ,現在的問題就轉變成了:如何通過 CSS 繪制這樣一個圖形?

CSS如何實現漸變提示框

1. 萬能的 gradient

沒有什么圖形是 CSS 漸變 繪制不出來的,這個也不例外。首先我們把這個圖形進行分解,這里可以分成一個圓角矩形和一個三角形,三角形比較容易,可以通過 conic-gradient 或者 linear-gradient 繪制

CSS如何實現漸變提示框

圓角矩形就稍微有點麻煩了,不過還是可以分解的,如下

CSS如何實現漸變提示框

可以由4個徑向漸變和2個線性漸變合成,用代碼實現就是

tips{
  -webkit-mask-image: 
    /*4個徑向漸變和2個線性漸變*/
    radial-gradient(circle at 5px 5px, green 5px,transparent 0),
    radial-gradient(circle at 5px 5px, green 5px,transparent 0),
    radial-gradient(circle at 5px 5px, green 5px,transparent 0),
    radial-gradient(circle at 5px 5px, green 5px,transparent 0),
    linear-gradient(red,red),
    linear-gradient(blue,blue);
  -webkit-mask-size:
    10px 10px,
      10px 10px,
    10px 10px,
    10px 10px,
    100% calc(100% - 15px),
    calc(100% - 10px) calc(100% - 5px)
  -webkit-mask-position:
    left top,
    right top,
    left 0 bottom 5px,
    right 0 bottom 5px,
    left 5px,
    5px top;
  -webkit-mask-repeat: no-repeat
}

只要有點耐心,都可以很順利的寫出來

但是...

太長了,有很多重復的(4個radial-gradient),非常啰嗦,有沒有什么辦法優化呢?這里有一個技巧,碰到重復有規律的東西,可以多想想 repeat,利用背景的平鋪特性,合理設置背景尺寸就可以了,如下

CSS如何實現漸變提示框

可以看到,背景尺寸設置成 calc(100% - 10px) 就可以達到平鋪效果,代碼實現就是

tips{
  -webkit-mask-image: 
    /*只需要一個徑向漸變即可*/
    radial-gradient(circle at 5px 5px, green 5px,transparent 0),
    linear-gradient(red,red),
    linear-gradient(blue,blue);
  -webkit-mask-size:
    calc(100% - 10px) calc(100% - 15px),/*圓角的尺寸,高度由于還需要減去三角形尺寸,所以多了5px*/
    100% calc(100% - 15px),
    calc(100% - 10px) calc(100% - 5px);
  -webkit-mask-position:
    left top,
    left 5px,
    5px top;
  -webkit-mask-repeat: repeat,no-repeat,no-repeat;
}

是不是精簡了許多?然后再把三角形的合過來就行了,可以得到如下效果

CSS如何實現漸變提示框

完整代碼可訪問 tooltips-mask-gradient (codepen.io)

https://codepen.io/xboxyan/pen/KKWRWOj

2. 自適應的svg

盡管做了一些優化,上面的代碼量仍然非常可觀,有沒有更加簡便的方式呢?

想到了 svg...

一般情況下,svg 路徑是固定尺寸的,只能 等比縮放 ,無法做到自適應。不過基本圖形是支持自適應的,可以設置百分比尺寸,比如 <rect>

<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%'>
   <rect rx="5" width='100%' height='100%'/>
</svg>

rx 可以設置矩形的圓角,當不設置 ry 時,默認與 rx  相同

這樣一個 svg 是可以自適應的,在改變尺寸的情況下不會變形(注意觀察圓角),如下

CSS如何實現漸變提示框

三角形就很容易了,可以用 <polygon> 實現

<svg xmlns='http://www.w3.org/2000/svg'>
  <polygon points='0 0,10 0,5 5' />
</svg>

然后,把兩段 svg 直接用作遮罩背景就行了,可以用 mask-size 和 mask-position 分別設置 尺寸位置

tips{
  -webkit-mask-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><polygon points='0 0,10 0,5 5' /></svg>"),url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><rect rx='6' width='100%' height='100%'/></svg>");
  -webkit-mask-size: 10px 5px, 100% calc(100% - 5px);
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center bottom, 0 0;
}

svg 用作背景需要在前面添加 data:image/svg+xml ,并且內容需要轉義,詳細可參考這篇文章:

學習了,CSS中內聯SVG圖片有比Base64更好的形式

https://www.zhangxinxu.com/wordpress/2018/08/css-svg-background-image-base64-encode/

還是挺不錯的,代碼量也不多,也比較容易理解,實時效果如下

CSS如何實現漸變提示框

完整代碼可訪問 tooltips-mask-svg (codepen.io)

https://codepen.io/xboxyan/pen/poeVrqB

三、paint 繪制

再來介紹一種未來的解決方式, CSS paint 。關于 CSS paint,又稱 “CSS 界的繪圖板”,簡單來說,就是用 canvas 繪圖的方式來繪制背景,canvas 幾乎什么都能繪制吧,所以這是一種更為通用的解決方案。想快速了解  CSS paint 的可以參考這一篇入門文章:

CSS屆的繪圖板CSS Paint API簡介

https://www.zhangxinxu.com/wordpress/2018/11/css-paint-api-canvas/

不過目前僅支持 Chrome,兼容性如下

CSS如何實現漸變提示框

不過并不影響我們的學習,畢竟是未來的解決方案,先看看大致的語法,如下

1、首先,JS 注冊模塊 registerPaint

// paint-tips.js
registerPaint('tips-bg', class {
    paint(ctx, size, properties) {
       // 在這里繪制背景,語法和canvas類似
    }
});

2、接著,JS 添加模塊 CSS.paintWorklet.addModule

if (window.CSS) {
    CSS.paintWorklet.addModule('paint-tips.js');
}

3、最后,CSS 中使用 paint(tips-bg)

tips{
  -webkit-mask-image: paint(tips-bg); /*這里作為遮罩背景使用*/
}

下面就來繪制提示框了,如果仍然借助 mask ,那么問題就變成了:如何通過 canvas 繪制這樣一個圖形?

CSS如何實現漸變提示框

在 canvas 中,相對于 CSS 來說, 這類圖形簡直就是小兒科,只需要使用 lineToarc 兩個指令就可以繪制了。最關鍵的一點是,這里的尺寸是實時渲染的,可以通過 size 來獲取

關于 canvas 學習,這里推薦一下張鑫旭老師的 Canvas API中文文檔,api 和 案例比 mdn 文檔清晰太多

https://www.canvasapi.cn/

繪制代碼如下(下面就是很普通的 canvas 代碼了,其實就是幾段線段連接起來,然后填充純色)

registerPaint('tips-bg', class {
    paint(ctx, size) { // ctx為繪制上下文,size為容器尺寸
      const { width,height } = size; // 容器尺寸
      const radius = 5; // 圓角大小
      const deg = Math.PI / 2;
      const edge = 5; // 三角形大小
      const pos = width / 2; // 三角形位置
      ctx.beginPath();
      ctx.moveTo(radius,0);
      ctx.lineTo(width-2*radius,0);
      ctx.arc(width-radius,radius,radius,-deg,0);
      ctx.lineTo(width,height-2*radius-edge);
      ctx.arc(width-radius,height-radius-edge,radius,0,deg);
      ctx.lineTo(pos+edge,height-edge);
      ctx.lineTo(pos,height);
      ctx.lineTo(pos-edge,height-edge);
      ctx.lineTo(radius,height-edge);
      ctx.arc(radius,height-radius-edge,radius,deg,2*deg);
      ctx.lineTo(0,radius-edge);
      ctx.arc(radius,radius,radius,-2*deg,-deg);
      ctx.closePath();
      ctx.fillStyle = '#000';
      ctx.fill();
   }
});

實時效果如下

CSS如何實現漸變提示框

完整代碼可訪問 tooltips-mask-paint (codepen.io)

https://codepen.io/xboxyan/pen/JjWvxEN

另外,也可以通過 CSS 變量進行自定義,比如定義一個--r為圓角大小,--t為三角形大小

<tips style="--r:5;--t:5"></tips>
registerPaint('tips-bg', class {
  static get inputProperties() { // 定義允許的自定義屬性
    return [
      '--r',
      '--t'
    ]
  }
  paint(ctx, size, properties) { // properties為自定義屬性
    const radius = Number(properties.get('--r'));
    const edge = Number(properties.get('--t'));
    // ...
  }
})

可以看到繪制是實時更新的(改變圓角),無需 JS 額外處理,實時效果如下

CSS如何實現漸變提示框

完整代碼可訪問 tooltips-mask-paint-var (codepen.io)

https://codepen.io/xboxyan/pen/JjWvVMd

四、描邊效果

有時候提示框可能還會有描邊的效果,比如這樣的

CSS如何實現漸變提示框

這類帶描邊的其實以上方式都不太適用,clip-pathmask 都無法實現描邊,不過有一個邊框生成方案可以參考:

有意思!不規則邊框的生成方案 (juejin.cn)

https://juejin.cn/post/6944892753402822686

可惜效果不是特別完美(略微模糊)

如果尺寸固定,那么可以直接使用 svg 方式,參考這篇文章:

用SVG實現一個優雅的提示框 (juejin.cn)

https://juejin.cn/post/6926353919333531661

就目前而言,確實沒有比較好的實現方案(有更好的實現方式歡迎補充,我暫時想不出來了),不過如果借助 CSS paint ,那一切就都有可能了!只需要在 paint 函數中繪制邊框和背景就行了

繪制代碼如下

registerPaint('tips-bg', class {
    paint(ctx, size) {
      const { width,height } = size; // 容器尺寸
      const radius = 5; // 圓角大小
      const deg = Math.PI / 2;
      const edge = 5; // 三角形大小
      const pos = width / 2; // 三角形位置
      const lineWidth = 2; // 描邊寬度
      ctx.beginPath();
      ctx.moveTo(radius+lineWidth,lineWidth);
      ctx.lineTo(width-2*radius-lineWidth,lineWidth);
      ctx.arc(width-radius-lineWidth,radius+lineWidth,radius,-deg,0);
      ctx.lineTo(width-lineWidth,height-2*radius-edge-lineWidth);
      ctx.arc(width-radius-lineWidth,height-radius-edge-lineWidth,radius,0,deg);
      ctx.lineTo(pos+edge,height-edge-lineWidth);
      ctx.lineTo(pos,height-lineWidth);
      ctx.lineTo(pos-edge,height-edge-lineWidth);
      ctx.lineTo(radius+lineWidth,height-edge-lineWidth);
      ctx.arc(radius+lineWidth,height-radius-edge-lineWidth,radius,deg,2*deg);
      ctx.lineTo(lineWidth,radius+lineWidth);
      ctx.arc(radius+lineWidth,radius+lineWidth,radius,-2*deg,-deg);
      ctx.closePath();
      const gradient = ctx.createLinearGradient(0, 0, width, 0); // 漸變背景
      gradient.addColorStop(0, '#F57853');
      gradient.addColorStop(1, '#F8B578');
      ctx.fillStyle = gradient; 
      ctx.fill();
      ctx.strokeStyle = '#FBF8F8'; // 繪制邊框
      ctx.lineWidth = lineWidth;
      ctx.lineCap = 'round';
      ctx.stroke();
   }
});
tips{
  /* -webkit-mask-image: paint(tips-bg); */
  background: paint(tips-bg); /*不再借助mask,純js繪制背景,包括漸變*/
}

實時效果如下

CSS如何實現漸變提示框

完整代碼可訪問 tooltips-paint-stroke (codepen.io)

https://codepen.io/xboxyan/pen/QWpxdVp

五、總結和說明

以上針對 tooltips 布局共介紹了3種不同類型的實現方式,分別是 clip-pathmaskCSS paint。其中 mask 的實現重點其實是CSS圖形的繪制,主要有 漸變svg 兩種,雖然 漸變 的寫法稍微復雜一點,但是最為通用,其他方式可能換一種布局就不適用了。現在總結一下要點:

  • 可以用多個容器重疊配合 clip-path 實現復雜的自適應效果

  • 在使用 CSS 漸變繪制圖形時,相同的形狀充分利用平鋪特性

  • svg 基本形狀支持百分比尺寸,用作背景同樣有效,可以使用多張背景來組合

  • CSS paint 是未來的最佳解決方式,也能輕易的實現描邊效果

  • CSS paint 唯一的缺陷是兼容性不夠好(現僅支持 Chrome 65+ ),但是值得學習

當然,這些方式不僅僅是實現本文的布局而已,更多的是提供一種思路,下次碰到其他的“異形布局”也能馬上聯想出相應的解決方案,而不是選擇“切圖.png”

感謝各位的閱讀,以上就是“CSS如何實現漸變提示框”的內容了,經過本文的學習后,相信大家對CSS如何實現漸變提示框這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

css
AI

本溪| 明溪县| 望城县| 扶风县| 北流市| 柳江县| 武宁县| 武乡县| 沁源县| 阿瓦提县| 临澧县| 喀喇| 祁门县| 错那县| 兴隆县| 鲁山县| 德江县| 巧家县| 景泰县| 汤原县| 饶河县| 丹东市| 新巴尔虎右旗| 连平县| 安丘市| 双柏县| 宜城市| 华安县| 洛扎县| 镇远县| 永康市| 齐齐哈尔市| 凤山市| 深圳市| 高阳县| 罗江县| 厦门市| 奉节县| 深泽县| 玉屏| 四平市|