- Notifications
You must be signed in to change notification settings - Fork2.1k
Description
今天,有个群友问了我这么一个问题,如果不想切图,是否有办法实现带渐变边框的字体效果?如下所示:
本文,就将尝试一下,在 CSS 中,我们可以如何尽可能的实现这种渐变边框字体效果。
元素叠加
首先,比较容易想到的写法是通过元素叠加实现。
- 元素本身实现文字效果本身
- 通过元素的伪元素,配合
background-clip: text实现渐变文字,并且通过 transform 或者设置大几号的文字,实现渐变字体 - 将(1)(2)进行叠加
我们尝试一下这种方式:
<divdata-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 滤镜实现
到这里,我又想到,在之前,写过的两篇文章:
我们借助了 SVG 滤镜能够实现对元素的腐蚀(变薄)或扩张(加粗)。
看看原理,feMorphology 为形态滤镜,它的输入源通常是图形的 alpha 通道,用来它的两个操作可以使源图形腐蚀(变薄)或扩张(加粗)。
使用属性operator 确定是要腐蚀效果还是扩张效果。使用属性radius 表示效果的程度,可以理解为笔触的大小。
- operator:
erode腐蚀模式,dilate为扩张模式,默认为erode - radius:笔触的大小,接受一个数字,表示该模式下的效果程度,默认为 0
我们将这个滤镜简单的应用到文字上看看效果:
<divclass="g-text"><p>Normal Text</p><pclass="dilate">Normal Text</p><pclass="erode">Normal Text</p></div><svgwidth="0"height="0"><filterid="dilate"><feMorphologyin="SourceAlpha"result="DILATED"operator="dilate"radius="3"></feMorphology></filter><filterid="erode"><feMorphologyin="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 的腐蚀模式,实现被细化的文字
- 将两者叠加起来
代码如下:
<divdata-text="123/678"></div><divdata-text="123/678"></div><divdata-text="123/678"></div><svgwidth="0"height="0"><filterid="outline"><feMorphologyin="SourceAlpha"result="ERODE"operator="erode"radius="2"></feMorphology><feFloodflood-color="#fff"flood-opacity="1"result="flood"></feFlood><feCompositein="flood"in2="ERODE"operator="in"result="OUTLINE"></feComposite><feMerge><feMergeNodein="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 实现的方式:
<divclass="wrapper"><spanclass="text"data-text="1234567890"></span><spanclass="text"data-text="我能吞下玻璃而不伤身体"></span></div>
.wrapper {position: relative;font-size:128px;--stroke-width:12px;--background-gradient:linear-gradient(red0%, green100%);--text-gradient:linear-gradient(white0%, cyan100%);}.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 会更为强大。
好了,本文到此结束,希望本文对你有所帮助 :)
想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 --iCSS前端趣闻 😄
更多精彩 CSS 技术文章汇总在我的Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。






