今天,有個群友問了我這麼一個問題,如果不想切圖,是否有辦法實現帶漸變邊框的字型效果?如下所示:
本文,就將嘗試一下,在 CSS 中,我們可以如何儘可能的實現這種漸變邊框字型效果。
元素疊加
首先,比較容易想到的寫法是透過元素疊加實現。
- 元素本身實現文字效果本身
- 透過元素的偽元素,配合
background-clip: text
實現漸變文字,並且透過 transform 或者設定大幾號的文字,實現漸變字型 - 將(1)(2)進行疊加
我們嘗試一下這種方式:
<div data-text="4"></div>
div {
position: relative;
width: 300px;
height: 150px;
font-size: 100px;
text-align: center;
font-weight: bold;
&::before,
&::after {
content: attr(data-text);
position: absolute;
inset: 0;
color: #000;
}
&::before {
transform: scale(1.1);
background: linear-gradient(cyan, #fc0);
background-clip: text;
color: transparent;
}
}
這裡,我們讓 before 偽元素
和 after 偽元素
兩個偽元素進行具體內容的展示,after 偽元素
只展示具體的文字,字號為 100px
,而before 偽元素
放大一點點後疊加在另外一個偽元素下面,效果如下:
可以看到,這種方式,邊框並不均勻。
而且,如果字數更多,效果更差:
所以,透過疊加實現,顯然不可取。
透過 SVG feMorphology 濾鏡實現
到這裡,我又想到,在之前,寫過的兩篇文章:
- CSS 奇技淫巧 | 巧妙實現文字二次加粗再加邊框
- 有意思!不規則邊框的生成方案
我們藉助了 SVG 濾鏡能夠實現對元素的腐蝕(變薄)或擴張(加粗)。
看看原理,feMorphology 為形態濾鏡,它的輸入源通常是圖形的 alpha 通道,用來它的兩個操作可以使源圖形腐蝕(變薄)或擴張(加粗)。
使用屬性 operator
確定是要腐蝕效果還是擴張效果。使用屬性 radius
表示效果的程度,可以理解為筆觸的大小。
- operator:
erode
腐蝕模式,dilate
為擴張模式,預設為erode
- radius:筆觸的大小,接受一個數字,表示該模式下的效果程度,預設為 0
我們將這個濾鏡簡單的應用到文字上看看效果:
<div class="g-text">
<p>Normal Text</p>
<p class="dilate">Normal Text</p>
<p class="erode">Normal Text</p>
</div>
<svg width="0" height="0">
<filter id="dilate">
<feMorphology in="SourceAlpha" result="DILATED" operator="dilate" radius="3"></feMorphology>
</filter>
<filter id="erode">
<feMorphology in="SourceAlpha" result="ERODE" operator="erode" radius="1"></feMorphology>
</filter>
</svg>
p {
font-size: 64px;
}
.dilate {
filter: url(#dilate);
}
.erode {
filter: url(#erode);
}
效果如下:最左邊的是正常文字,中間的是擴張的模式,右邊的是腐蝕模式,看看效果,非常好理解:
如果能理解到這一點,我們可以嘗試:
- 利用
background-clip: text
實現漸變文字 - 利用 SVG feMorphology 的腐蝕模式,實現被細化的文字
- 將兩者疊加起來
程式碼如下:
<div data-text="123/678"></div>
<div data-text="123/678"></div>
<div data-text="123/678"></div>
<svg width="0" height="0">
<filter id="outline">
<feMorphology in="SourceAlpha" result="ERODE" operator="erode" radius="2"></feMorphology>
<feFlood flood-color="#fff" flood-opacity="1" result="flood"></feFlood>
<feComposite in="flood" in2="ERODE" operator="in" result="OUTLINE"></feComposite>
<feMerge>
<feMergeNode in="OUTLINE" />
</feMerge>
</filter>
</svg>
div {
position: relative;
width: 100vw;
height: 150px;
font-size: 120px;
font-weight: bold;
text-align: center;
&::before,
&::after {
content: attr(data-text);
position: absolute;
inset: 0;
}
&::before {
color: transparent;
background: linear-gradient(0deg, #da00ff, #2a79b7, #7e3eff);
background-clip: text;
}
&::after {
filter: url(#outline);
}
}
div:nth-child(2) {
font-family: 'Cherry Bomb One', cursive;
font-size: 90px;
}
div:nth-child(3) {
font-family: 'Darumadrop One', cursive;
font-size: 150px;
}
基於此,看看效果,這裡我嘗試了 3 種不同的字型:
看著還是挺不錯的,利用 SVG 能夠使源圖形腐蝕(變薄)或擴張(加粗)的能力,我們巧妙的實現了文字的漸變邊框效果。
完整的 DEMO,你可以戳這裡:CodePen Demo -- SVG 實現漸變邊框字型
文字邊框 -webkit-text-stroke
結束了嗎?還沒有。一開始我就有想過使用 -webkit-text-stroke
來實現。
但是轉念一想,認為 -webkit-text-stroke
無法實現漸變邊框,並且它需要使用 -webkit-
字首,可能會存在相容問題,結果在討論的過程中,牛逼的群友給出了使用 -webkit-text-stroke
實現的方式:
<div class="wrapper">
<span class="text" data-text="1234567890"></span>
<span class="text" data-text="我能吞下玻璃而不傷身體"></span>
</div>
.wrapper {
position: relative;
font-size: 128px;
--stroke-width: 12px;
--background-gradient: linear-gradient(red 0%, green 100%);
--text-gradient: linear-gradient(white 0%, cyan 100%);
}
.text {
position: relative;
}
.text::before,
.text::after {
content: attr(data-text);
display: block;
background-clip: text;
color: transparent;
}
.text::before {
position: absolute;
inset: 0;
background-image: var(--background-gradient);
-webkit-text-stroke: var(--stroke-width);
}
.text::after {
position: relative;
z-index: 1;
background-image: var(--text-gradient);
}
-webkit-text-stroke
解法思路本質上也是用的它的背景色,使用了 stroke 的偽元素只是為了讓其字更大一圈,從而背景色可以露出來。
並且,-webkit-text-stroke
的邊框顏色,可以支援直接設定漸變色,如此一來,我們就得到非常完美的效果:
並且,從 CanIUse - text-stroke,到今天,-webkit-text-stroke
的相容性已經非常好了:
我們完全可以放心使用 -webkit-text-stroke
設定文字的各種型別邊框效果。
完整的 DEMO,你可以戳這裡:CodePen Demo -- CSS text stroke with gradient By Rex Zeng
最後
簡單總結一下,綜上所述,其實 -webkit-text-stroke
是最簡單最便捷的實現漸變文字邊框的方式。當然,SVG 方法也有其優勢,如果需要多重邊框效果,甚至是多重漸變文字邊框效果,此時,SVG 會更為強大。
好了,本文到此結束,希望本文對你有所幫助 😃
更多精彩 CSS 技術文章彙總在我的 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。
如果還有什麼疑問或者建議,可以多多交流,原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。