自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

不一樣的SVG!SVG在CSS背景平鋪中的應(yīng)用

開發(fā) 前端
再次介紹一些你可能沒用過的SVG小技巧。相比普通的按鈕,多個左右兩個小裝飾,如果是你,會怎樣實現(xiàn)呢?

再次介紹一些你可能沒用過的SVG小技巧。

再次介紹一些你可能沒用過的SVG小技巧。

有時候會遇到一些完全相同的圖形,如果能用上 CSS背景平鋪,那就再合適不過了。舉個例子,有這樣一個按鈕。

相比普通的按鈕,多個左右兩個小裝飾,如果是你,會怎樣實現(xiàn)呢?

假設(shè)這個小圖標(biāo)是a.svg,想了一下,應(yīng)該有以下幾種方式。

1.偽元素

剛好用上::before和::after,設(shè)置相同的背景就行了,示意如下:

button::before,
button::after{
  content:'';
  background: url(a.svg)
}

2. 多重背景

利用 CSS背景可以疊加的特性,設(shè)置兩個背景就可以了,分別定位,示意如下:

button{
  background: url(a.svg) 10px center no-repeat,url(a.svg) right 10px top center no-repeat
}

這兩種方式都是不錯的方式,但是感覺還是有些浪費,畢竟把兩個相同的圖案重復(fù)寫了兩遍。

為啥不能直接用背景平鋪呢?因為無法直接設(shè)置平鋪的間隔,就像這樣。

這時,如果能充分發(fā)揮SVG的特性,就可以僅僅使用平鋪的方式來實現(xiàn)我們想要的效果了,一起看看吧~

一、SVG的自適應(yīng)和viewBox

就以上面的小圖標(biāo)為例,從 Figma中可以復(fù)制這段svg,如下:

<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M15.021 8.028L15 8.027c-.262-.26-.876-.747-2.008-.701.13-.314.027-1.204-.676-1.227.179.574-.803.974-1.361 1.155-.484.156-1.025.344-1.16.622l-.437-.003.002-.43-.276-.001-.004.428-.25-.002c-.028-.022-.058-.047-.091-.07a.643.643 0 0 0-.316-.29.663.663 0 0 0-.21-.22 3.071 3.071 0 0 0-.109-.157l.002-.21.43.004.003-.277-.43-.004.002-.436c.283-.127.478-.667.644-1.152.19-.555.606-1.53 1.18-1.341-.013-.704-.902-.822-1.216-.695.063-1.135-.417-1.754-.67-2.02V.977L8.036.99 8.028.977l-.001.02c-.26.263-.747.877-.701 2.009-.314-.13-1.204-.027-1.228.676.574-.179.974.803 1.155 1.362.157.484.345 1.025.622 1.159l-.003.437-.43-.002v.277l.427.003-.002.25c-.022.028-.046.058-.069.091a.643.643 0 0 0-.29.317.664.664 0 0 0-.222.21 3.07 3.07 0 0 0-.156.108l-.21-.002.004-.43-.276-.002-.004.43-.436-.002c-.127-.283-.667-.478-1.152-.644-.555-.19-1.53-.606-1.341-1.18-.704.013-.822.902-.695 1.216-1.135-.063-1.754.417-2.02.67H.977l.012.012-.012.009.02.001c.263.26.877.747 2.009.702-.13.314-.027 1.203.676 1.227-.179-.574.803-.974 1.362-1.155.484-.157 1.024-.345 1.159-.622l.437.003-.002.43h.277l.003-.427.25.002c.028.022.058.046.091.069a.643.643 0 0 0 .317.29c.058.101.135.172.21.222.04.06.077.114.108.156l-.002.21-.43-.004-.002.276.43.004-.002.437c-.283.127-.478.666-.644 1.15-.19.556-.606 1.532-1.18 1.342.013.705.902.822 1.216.696-.063 1.134.417 1.753.67 2.02v.022l.012-.011c.004.003.006.007.009.012l.001-.021c.26-.263.747-.877.702-2.009.314.13 1.203.027 1.227-.676-.574.179-.974-.803-1.155-1.362-.157-.483-.345-1.024-.622-1.159l.003-.437.43.002v-.277l-.427-.003.002-.25c.022-.028.046-.058.069-.091a.643.643 0 0 0 .29-.317.664.664 0 0 0 .222-.21c.06-.04.114-.077.156-.108l.21.002-.004.43.276.002.004-.43.437.002c.127.283.666.478 1.15.644.556.19 1.532.606 1.342 1.18.705-.013.823-.902.696-1.216 1.134.063 1.753-.417 2.02-.67h.022a1.093 1.093 0 0 1-.011-.012c.003-.004.007-.006.012-.009h-.002z" fill="#000"/>
</svg>

嗯,看著非常亂,沒關(guān)系,我們不必關(guān)注里面的細(xì)節(jié)。

我們直接放在 html 中來展示這段svg,效果是這樣的。

因為這段 svg有自帶的尺寸,最后展示的就是16 * 16的大小。

如果我們手動改變這個svg的尺寸呢?為了方便觀察,我們給svg添加一個邊框,如下:

svg{
	width: 200px;
  height: 100px;
  outline: 1px dashed;
}

你猜會是什么樣的?

下面有 3 個選項。

思考一分鐘...

思考完成,答案是A,你猜對了嗎?

為什么會這樣呢?有點類似于object-fit:contain的效果。其實這是viewBox造成的,viewBox會按照尺寸等比放大從而鋪滿整個svg。

有關(guān) viewBox的更多介紹,可以參考張鑫旭老師的這篇文章:理解SVG viewport,viewBox,preserveAspectRatio縮放。

如果去除viewBox,svg內(nèi)部該是什么樣就是什么樣,也就是仍然是16*16的大小。

<!--去除viewBox屬性-->
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg">
  ...
</svg>

結(jié)果如下:

也就是說,在去除viewBox之后,無論svg尺寸是多少,里面的圖標(biāo)都不會變化。

看似好像沒什么用?

其實用處可大了,可以讓背景以我們想要的方式平鋪,那就來看接下來的應(yīng)用。

二、自適應(yīng)尺寸與背景平鋪

現(xiàn)在來簡單實現(xiàn)文章開頭所示的按鈕效果。html很簡單,就一個標(biāo)簽。

<button>召喚卡牌</button>

然后簡單裝飾一下,繪制圓角和背景。

button{
  border: 0;
  outline: 0;
  padding: 8px 36px;
  font-size: 12px;
  line-height: 16px;
  border-radius: 30px;
  color: #FFEFDB;
  background: #FF2A2A;
}

效果如下:

接下來,我們要用上前面的那段svg,先去除viewBox屬性,為了能夠通過背景尺寸控制svg大小,我們可以將svg的尺寸改成100%。

示意如下:

<svg width="100%" height="100%" fill="none" xmlns="http://www.w3.org/2000/svg">
  ...
</svg>

然后將這段svg轉(zhuǎn)換成css內(nèi)聯(lián)格式,推薦用張鑫旭老師的在線轉(zhuǎn)換工具。

SVG在線壓縮合并工具。

可以得到這樣一段。

--icon: url("data:image/svg+xml,%3Csvg width='16' height='16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M15.021 8.028L15 8.027c-.262-.26-.876-.747-2.008-.701.13-.314.027-1.204-.676-1.227.179.574-.803.974-1.361 1.155-.484.156-1.025.344-1.16.622l-.437-.003.002-.43-.276-.001-.004.428-.25-.002c-.028-.022-.058-.047-.091-.07a.643.643 0 0 0-.316-.29.663.663 0 0 0-.21-.22 3.071 3.071 0 0 0-.109-.157l.002-.21.43.004.003-.277-.43-.004.002-.436c.283-.127.478-.667.644-1.152.19-.555.606-1.53 1.18-1.341-.013-.704-.902-.822-1.216-.695.063-1.135-.417-1.754-.67-2.02V.977L8.036.99 8.028.977l-.001.02c-.26.263-.747.877-.701 2.009-.314-.13-1.204-.027-1.228.676.574-.179.974.803 1.155 1.362.157.484.345 1.025.622 1.159l-.003.437-.43-.002v.277l.427.003-.002.25c-.022.028-.046.058-.069.091a.643.643 0 0 0-.29.317.664.664 0 0 0-.222.21 3.07 3.07 0 0 0-.156.108l-.21-.002.004-.43-.276-.002-.004.43-.436-.002c-.127-.283-.667-.478-1.152-.644-.555-.19-1.53-.606-1.341-1.18-.704.013-.822.902-.695 1.216-1.135-.063-1.754.417-2.02.67H.977l.012.012-.012.009.02.001c.263.26.877.747 2.009.702-.13.314-.027 1.203.676 1.227-.179-.574.803-.974 1.362-1.155.484-.157 1.024-.345 1.159-.622l.437.003-.002.43h.277l.003-.427.25.002c.028.022.058.046.091.069a.643.643 0 0 0 .317.29c.058.101.135.172.21.222.04.06.077.114.108.156l-.002.21-.43-.004-.002.276.43.004-.002.437c-.283.127-.478.666-.644 1.15-.19.556-.606 1.532-1.18 1.342.013.705.902.822 1.216.696-.063 1.134.417 1.753.67 2.02v.022l.012-.011c.004.003.006.007.009.012l.001-.021c.26-.263.747-.877.702-2.009.314.13 1.203.027 1.227-.676-.574.179-.974-.803-1.155-1.362-.157-.483-.345-1.024-.622-1.159l.003-.437.43.002v-.277l-.427-.003.002-.25c.022-.028.046-.058.069-.091a.643.643 0 0 0 .29-.317.664.664 0 0 0 .222-.21c.06-.04.114-.077.156-.108l.21.002-.004.43.276.002.004-.43.437.002c.127.283.666.478 1.15.644.556.19 1.532.606 1.342 1.18.705-.013.823-.902.696-1.216 1.134.063 1.753-.417 2.02-.67h.022a1.093 1.093 0 0 1-.011-.012c.003-.004.007-.006.012-.009h-.002z' fill='%23FFEFDB'/%3E%3C/svg%3E")

接著,將這段svg背景放到按鈕中。

button{
  background: var(--icon) #FF2A2A;
}

效果如下:

很明顯,此時這個svg圖標(biāo)背景默認(rèn)尺寸是充滿整個容器的,也就是100% * 100%。如果希望右邊也出現(xiàn)平鋪一個圖標(biāo),可以減小背景尺寸,比如。

button{
  background: var(--icon) #FF2A2A;
  background-size: calc(100% - 48px)
}

效果如下:

然后改變水平位置。

button{
  background: var(--icon) #FF2A2A;
  background-size: calc(100% - 48px);
  background-position: 16px;
}

效果如下:

左右已經(jīng)出現(xiàn)圖標(biāo)了,現(xiàn)在只需要垂直居中就可以了,這個也很好實現(xiàn),設(shè)置尺寸為圖標(biāo)本身大小,然后改變背景位置就行了。

button{
  background: var(--icon) #FF2A2A;
  background-size: calc(100% - 48px) 16px;
  background-position: 16px center;
}

效果如下:

垂直方向也平鋪了,所以還需要改變一下平鋪方式,僅限水平方向。

button{
  background: var(--icon) #FF2A2A;
  background-size: calc(100% - 48px) 16px;
  background-position: 16px center;
  background-repeat: repeat-x;
}

這樣就僅僅使用平鋪完成了想要的效果!

是不是有些不可思議?下面是一個示意圖,紫色圓圈代表圖標(biāo),紫色邊框代表svg尺寸,也就是背景尺寸,設(shè)置為100% - 36px后,水平方向的平鋪就可以顯示兩個圓圈了,然后適當(dāng)移動背景位置,就可以看到左右兩邊的圖標(biāo)了。

當(dāng)然這種實現(xiàn)也是完全是自適應(yīng)的,無論什么尺寸都可以完美適配。

完整代碼可以查看以下鏈接:

  • CSS & SVG repeat button (juejin.cn)[1]
  • CSS & SVG repeat button (codepen.io)[2]

三、有時候可替代徑向漸變

里面有提到用徑向漸變的方式來繪制內(nèi)凹圓角,但是漸變一直都是一個非常難學(xué)的技巧,語法非常多,一般同學(xué)表示接受不了。

這里就采用 SVG來代替徑向漸變的方式來實現(xiàn)這樣的優(yōu)惠券效果。

首先,我們用設(shè)計軟件隨便畫個圓,這里以Figma為例,然后復(fù)制出SVG。

其實就是這樣一段代碼。

<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="20" cy="20" r="20" fill="#FF336F"/>
</svg>

非常簡單吧。

然后去除viewBox,并且設(shè)置寬高為100%,這是為了讓SVG畫布尺寸撐滿整個容器。

<svg width="100%" height="100%" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="20" cy="20" r="20" fill="#FF336F"/>
</svg>

接著轉(zhuǎn)換成CSS內(nèi)聯(lián)格式。

--icon: url("data:image/svg+xml,%3Csvg width='100%' height='100%' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Ccircle cx='20' cy='20' r='20' fill='%23FF336F'/%3E%3C/svg%3E")

然后用在 CSS 背景中。

div{
  background: var(--icon);
}

目前效果是這樣的。

我們需要將這個圓分割到4個角落上,可以直接用背景平移的方式。

div{
  background: var(--icon);
  background-position: -20px -20px;
}

這樣就可以了,演示如下:

不過這樣還沒完,我們需要實現(xiàn)的反向圓角,所以這里需要用遮罩的方式,減去 4 個角落。

回到這里,我們只需要一個完整的背景,減去剛才的圓角就可以了,具體實現(xiàn)如下:

.coupon{
  background: linear-gradient(red,orange);
  -webkit-mask:linear-gradient(red,red), var(--icon);
  -webkit-mask-position: -20px -20px;
  -webkit-mask-composite: xor;
}

效果如下,其實和前面幾乎一致。

是不是沒有用到徑向漸變?

完整代碼可以查看以下鏈接:

  • CSS & SVG coupon (juejin.cn)[3]
  • CSS & SVG coupon (codepen.io)[4]

四、SVG還可以更靈活

有時候徑向漸變還是有很多局限的,復(fù)雜的圖形繪制不了或者成本很高。而 SVG就沒有這樣的限制了,如果能有一定的自適應(yīng)特性,相信可以更方便的解決問題。

比如這樣一個帶圓角的自適應(yīng)聚焦框,可能在大屏可視化比較常見,如下(CSS表示無能為力??)。

除了使用border-image實現(xiàn)以外,還可以采用背景平鋪來實現(xiàn)。

要實現(xiàn)背景平鋪,首先要考慮,哪個是平鋪最小單元?

思考一分鐘...

思考完成,答案還是A,你猜對了嗎?

為什么是A呢?其實要從全局視野來觀察,從全局來看,其實是由4個半圓弧組合而成,示意如下:

那么,如何用 CSS背景平鋪來實現(xiàn)呢?

思路是一致的,首先從設(shè)計稿把這段svg復(fù)制下來。

得到這樣一個片段。

<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M30 2C30 0.895431 29.1046 0 28 0C26.8954 0 26 0.895431 26 2V10C26 18.8366 18.8366 26 10 26H2C0.895431 26 0 26.8954 0 28C0 29.1046 0.895431 30 2 30C0.895431 30 0 30.8954 0 32C0 33.1046 0.895431 34 2 34H10C18.8366 34 26 41.1634 26 50V58C26 59.1046 26.8954 60 28 60C29.1046 60 30 59.1046 30 58C30 59.1046 30.8954 60 32 60C33.1046 60 34 59.1046 34 58V50C34 41.1634 41.1634 34 50 34H58C59.1046 34 60 33.1046 60 32C60 30.8954 59.1046 30 58 30C59.1046 30 60 29.1046 60 28C60 26.8954 59.1046 26 58 26H50C41.1634 26 34 18.8366 34 10V2C34 0.895431 33.1046 0 32 0C30.8954 0 30 0.895431 30 2ZM50 30C38.9543 30 30 38.9543 30 50C30 38.9543 21.0457 30 10 30C21.0457 30 30 21.0457 30 10C30 21.0457 38.9543 30 50 30Z" fill="#FF336F"/>
</svg>

然后去除viewBox,并且設(shè)置寬高為100%。

<svg width="100%" height="100%" fill="none" xmlns="http://www.w3.org/2000/svg">
  ...
</svg>

接著轉(zhuǎn)換成CSS內(nèi)聯(lián)格式。

--icon: url("data:image/svg+xml,%3Csvg width='100%' height='100%' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M30 2a2 2 0 1 0-4 0v8c0 8.837-7.163 16-16 16H2a2 2 0 1 0 0 4 2 2 0 1 0 0 4h8c8.837 0 16 7.163 16 16v8a2 2 0 1 0 4 0 2 2 0 1 0 4 0v-8c0-8.837 7.163-16 16-16h8a2 2 0 1 0 0-4 2 2 0 1 0 0-4h-8c-8.837 0-16-7.163-16-16V2a2 2 0 1 0-4 0zm20 28c-11.046 0-20 8.954-20 20 0-11.046-8.954-20-20-20 11.046 0 20-8.954 20-20 0 11.046 8.954 20 20 20z' fill='%23FF336F'/%3E%3C/svg%3E")

最后設(shè)置為CSS背景。

div{
  background: var(--icon);
}

效果如下:

此時無論容器尺寸是多少,這個背景位于左上角。

最后只需要改變一下背景的位置,設(shè)置負(fù)的偏移量,就可以平鋪到 4 個角落了。

div{
  background: var(--icon) #eee;
  background-position: -30px -30px;/*圖案的一半*/
}

動態(tài)示意如下:

是不是非常簡單的實現(xiàn)?

完整代碼可以查看以下鏈接:

  • CSS & SVG coner (juejin.cn)[5]
  • CSS & SVG coner (codepen.io)[6]

五、總結(jié)一下

以上就是本文的全部內(nèi)容了,一個成本非常小的 SVG小技巧,僅僅需要小小的改動,就能讓SVG自適應(yīng)背景平鋪,如下:

<!--去除viewBox屬性,并設(shè)置寬高100%-->
<svg width="100%" height="100%" fill="none" xmlns="http://www.w3.org/2000/svg">
  ...
</svg>

你學(xué)到了嗎?下面總結(jié)一下實現(xiàn)要點:

  • SVG默認(rèn)會根據(jù)viewBox填充整個畫布,有點類似于object-fit:contain的效果。
  • 去除viewBox后,無論svg尺寸是多少,里面的內(nèi)容大小都不會變化。
  • 利用這個特性,可以通過設(shè)置背景尺寸的方式,讓背景以我們想要的方式平鋪。
  • 有時候可替代徑向漸變,畢竟 SVG 比漸變還是容易很多。
  • 復(fù)雜的圖形漸變繪制不了或者成本很高,SVG還能更靈活。

[1]CSS & SVG repeat button (juejin.cn): https://code.juejin.cn/pen/7357275939322052658。

[2]CSS & SVG repeat button (codepen.io): https://codepen.io/xboxyan/pen/mdgjeeM。

[3]CSS & SVG coupon (juejin.cn): https://code.juejin.cn/pen/7357302135584718899。

[4]CSS & SVG coupon (codepen.io): https://codepen.io/xboxyan/pen/MWRBKbj。

[5]CSS & SVG coner (juejin.cn): https://code.juejin.cn/pen/7357294680330993702。

[6]CSS & SVG coner (codepen.io): https://codepen.io/xboxyan/pen/GRLBpLX。

責(zé)任編輯:姜華 來源: 前端偵探
相關(guān)推薦

2024-04-08 09:11:13

SVG前端CSS

2012-12-20 10:17:32

IT運維

2012-03-07 17:24:10

戴爾咨詢

2016-05-09 18:40:26

VIP客戶緝拿

2017-05-25 15:02:46

聯(lián)宇益通SD-WAN

2009-07-07 10:44:14

多態(tài)

2015-10-19 12:33:01

華三/新IT

2018-05-09 15:42:24

新零售

2009-02-04 15:43:45

敏捷開發(fā)PHPFleaPHP

2009-12-01 16:42:27

Gentoo Linu

2009-06-12 15:26:02

2011-02-28 10:38:13

Windows 8

2016-03-24 18:51:40

2013-01-11 18:10:56

軟件

2015-08-25 09:52:36

云計算云計算產(chǎn)業(yè)云計算政策

2015-08-04 14:49:54

Discover

2009-01-20 10:39:00

Windows7IE 8瀏覽器

2019-01-03 14:39:08

Oracle甲骨文ORACLE

2022-05-05 21:47:32

Linuxls 命令

2009-11-26 13:16:25

Open Suse
點贊
收藏

51CTO技術(shù)棧公眾號