CSS & SVG 繪制寫作網(wǎng)格線的三種方式
最近有同事問我這樣一個(gè)問題:需要繪制一個(gè)自適應(yīng)文本的寫作網(wǎng)格線,設(shè)計(jì)稿是這樣的。
寫作網(wǎng)格
其實(shí)就是一行行虛線,要求如下:
- 虛線的縱向間隔要跟隨行高自適應(yīng),確保文本在每一欄虛線上。
- 虛線后面的背景是動態(tài)的,可以是純色,可以是漸變,也可以是圖片。
繪制這樣的虛線,看似容易,其實(shí)暗藏玄機(jī),下面一起看看有哪些實(shí)現(xiàn)方式吧。
一、純色背景下的虛線
首先來看這種簡單情況,大可以通過兩層漸變覆蓋的方式實(shí)現(xiàn)。
假設(shè)文本行高是2,先繪制水平方向的。
注意,這里的背景尺寸是100% 2em,高度跟隨文字行高,所以高度是2em,效果如下:
然后,繪制縱向的實(shí)線,蓋在上面,為了區(qū)分,先用一個(gè)淺紅色來代替。
這樣就繪制了一個(gè)垂直平鋪,間隔為4px的虛線,效果如下:
應(yīng)該比較好理解吧,就是兩個(gè)方向上的漸變疊加。
然后,將這個(gè)紅色改成和底色相同的顏色就行了,比如這里是白色。
這樣就實(shí)現(xiàn)了純色下的虛線網(wǎng)格,效果如下:
二、漸變背景下的虛線
如果不是純色,而是漸變的呢?假設(shè)有一個(gè)這樣的背景。
如果直接用前面的方式,可能就變成了這樣。
白色直接把背后的漸變背景也覆蓋了。
那如何解決這個(gè)問題呢?
像這種疊加混合的情況一般都會想到混合模式,沒錯(cuò),這里也可以通過混合模式簡單處理。要用混合模式,必須要讓這兩層背景處于不同的容器中,然后使用mix-blend-mode。
這里使用了混合模式中的darken,這種模式可以去除白色部分,保留其他,效果如下:
完整代碼可以查看以下任意鏈接:
- CSS dot line mix-blend-mode (juejin.cn)[1]
- CSS dot line mix-blend-mode (codepen.io)[2]
- CSS dot line mix-blend-mode (runjs.work)[3]
三、通過錐形漸變繪制
下面再介紹一個(gè)比較硬核的繪制方式:錐形漸變(conic-gradient)[4]。
為什么說比較硬核呢?因?yàn)檫@種方式繪制出來的圖形就是完完全全的虛線,也沒有混合模式的諸多限制。
首先我們從圖形上分析,找到最小的重復(fù)單元,如下:
找到了,就是這個(gè),其實(shí)就是這個(gè)位于左上角的矩形,那么,如何通過錐形漸變來繪制呢?
注意:有同學(xué)可能會奇怪,這樣一個(gè)矩形線性漸變不是可以很輕松的實(shí)現(xiàn)嗎?確實(shí)可以,但是只能實(shí)現(xiàn)一個(gè),無法平鋪
看著好像不沾邊,下面帶你一步步演變。
首先是最原始的語法。
這是一個(gè)從透明到灰色的漸變,效果如下:
這才是錐形漸變的樣子!
然后,我們可以將漸變的分界線調(diào)整一下。
這樣就變成了一個(gè)邊界分明的正方形。
然后改變起始角度,通過from關(guān)鍵詞。
這樣起始角度就會從270deg的地方開始,如下:
接著,改變中心點(diǎn)的位置,默認(rèn)是水平垂直居中的,我們要改到左上角,需要用到??at?
?關(guān)鍵詞
這里改成了左上角40px,10px的地方,如下:
最后,改變背景的尺寸,默認(rèn)是寬高100%的,我們要改成實(shí)際需要的大小。
這樣就會自動平鋪展開,如下:
原理就是這樣,實(shí)際上的虛線比較小,應(yīng)該是4px 1px,所以實(shí)際應(yīng)用應(yīng)該是這樣。
效果如下:
完整代碼可以查看以下任意鏈接:
- CSS dot-line conic-gradient (juejin.cn)[5]
- CSS dot-line conic-gradient (codepen.io)[6]
- CSS dot-line conic-gradient (runjs.work)[7]
四、動態(tài)SVG背景繪制
最后再來介紹一個(gè)實(shí)現(xiàn)起來最容易的方式,就是“切圖”。
但是,這種“切圖”不同于一般的切圖,因?yàn)檫@個(gè)尺寸是動態(tài)的,要跟隨文字的行高變化而變化,所以需要采取一定的“手段”。
首先在繪圖軟件中繪制這樣一個(gè)圖形,例如下面是figma中繪制的。
外面的寬高無所謂,隨便設(shè)置??梢缘玫竭@樣一段SVG。
然后,我們將這個(gè)svg轉(zhuǎn)換成內(nèi)聯(lián) CSS格式。
推薦張鑫旭老師的在線轉(zhuǎn)換工具:SVG在線壓縮合并工具[8]。
直接用到背景上。
效果如下:
為啥這里的虛線都錯(cuò)位了呢?
這也是 SVG不同于常規(guī)圖片的一點(diǎn),在外部背景尺寸超過viewbox尺寸后,SVG 畫布會整體縮放,但是具體的元素并不會,具體表現(xiàn)是這樣的。
那么,有沒有辦法在畫布縮放的時(shí)候,里面的元素仍然位于左上角呢?就像這樣
當(dāng)然也是可以的,只需要將viewbox改為0 0 100% 100%就行了,或者干脆刪除(默認(rèn)就是100%),SVG的寬高也要改成100%,如下:
這樣一來,不管背景尺寸如何變化,內(nèi)部的虛線位置都不受影響,效果如下:
完整代碼可以查看以下任意鏈接
- svg dot-line (juejin.cn)[9]
- svg dot-line (codepen.io)[10]
- svg dot-line (runjs.work)[11]
除了上面這種方式,還可以換一種思路,讓默認(rèn)的虛線是居中的,這樣在放大后也是居中的,如下
這樣在不改變viewbox的情況下也能實(shí)現(xiàn)相同的效果,有興趣的小伙伴可以下去試一試。
五、總結(jié)一下優(yōu)缺點(diǎn)
以上共介紹了 3 種完全不同的繪制虛線的方式,原理各不相同,也有各自的優(yōu)缺點(diǎn),下面總結(jié)一下。
CSS 漸變混合模式的優(yōu)點(diǎn)在于實(shí)現(xiàn)思路比較簡單,很容易想到,純色背景優(yōu)先推薦,缺點(diǎn)是混合模式有一些局限性,比如在黑色背景下可能需要換一種模式了。
CSS 錐形漸變的優(yōu)點(diǎn)在于代碼實(shí)現(xiàn)簡單,不受結(jié)構(gòu)限制,缺點(diǎn)是有點(diǎn)不好理解,還有就是兼容性稍微差一些。
SVG 自適應(yīng)背景的優(yōu)點(diǎn)在于使用簡單,基本等同于“切圖”,缺點(diǎn)是需要掌握 SVG 的特性,而且無法直接通過 CSS 改變顏色,只能換圖。
綜合來講,如果兼容性沒有要求,首推第2種方式,其次是 SVG 方式,最后才是混合模式。
參考資料
[1]CSS dot line mix-blend-mode (juejin.cn): ??https://code.juejin.cn/pen/7185780439276060730。??
[2]CSS dot line mix-blend-mode (codepen.io): ??https://codepen.io/xboxyan/pen/ExpNBPr。??
[3]CSS dot line mix-blend-mode (runjs.work): ??https://runjs.work/projects/a0ec6e9e89f943a2。??
[4]錐形漸變(conic-gradient): ??https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/conic-gradient。??
[5]CSS dot-line conic-gradient (juejin.cn): ??https://code.juejin.cn/pen/7185788769595818042。??
[6]CSS dot-line conic-gradient (codepen.io): ??https://codepen.io/xboxyan/pen/GRBNbEN。??
[7]CSS dot-line conic-gradient (runjs.work): ??https://runjs.work/projects/dc01e87b2c62426b。??
[8]SVG在線壓縮合并工具: ??https://www.zhangxinxu.com/sp/svgo/。??
[9]svg dot-line (juejin.cn): ??https://code.juejin.cn/pen/7185803705722077219。??
[10]svg dot-line (codepen.io): ??https://codepen.io/xboxyan/pen/eYjBwxa。??
[11]svg dot-line (runjs.work): ??https://runjs.work/projects/c725bbf1830743b6。??