이 글에서는 CSS와 SVG를 사용하여 텍스트에 그라데이션, 획, 그림자 효과를 추가하는 방법을 소개합니다. 도움이 되길 바랍니다.
이런 일부 웹 활동 페이지에서 특수 처리된 제목 텍스트를 자주 볼 수 있습니다.
당분간 특수 글꼴은 무시하고 있는 디자인 초안의 레이어 스타일을 통해 확인할 수 있습니다. 총 3개의 텍스트 효과입니다. 각각 Gradient, Stroke, Projection
야심찬 프론트 엔드로서 당연히 그림을 직접 사용하지는 않겠습니다~ 여기서는 CSS와 SVG를 사용하여 구현합니다. , 살펴봅시다 Bar
알림: 기사에 많은 세부정보가 포함되어 있으므로 관심이 없으면 바로 아래로 이동하여 온라인 데모를 볼 수 있습니다.
먼저 살펴보겠습니다. CSS의 구현을 살펴보세요.
CSS에는 텍스트 그라데이션을 설정하는 직접적인 속성이 없습니다. 일반적으로 텍스트는 단색만 가능합니다. 그러나 배경 클리핑 background-clip
을 사용하여 배경 색상을 텍스트 영역에 표시할 수 있습니다. 텍스트에 그라데이션이 있는 것처럼 보입니다.background-clip
让背景色在文本区域显示出来,看着就像是文字有了渐变
<p class="text">为你定制 发现精彩</p>
.text{ background-image: linear-gradient(#FFCF02, #FF7352); background-clip: text; -webkit-background-clip: text; }
但是这样没什么效果,文字仍然是默认颜色
原因其实很简单,由于是裁剪的背景,最后展示的其实是背景颜色,有颜色的文字覆盖在背景之上,所以这里需要将文字颜色设置为透明就行了,用 color
和 -webkit-text-fill-color
都可以实现。
.text{ background-image: linear-gradient(#FFCF02, #FF7352); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; /*需要文字透明*/ }
这样就可以看到文字渐变效果了
再来看看 SVG 中的文字渐变。
SVG 中天然支持文字渐变,完全可以把文字当成普通的矢量路径,结构如下
<svg> <text>为你定制 发现精彩</text> </svg>
直接通过 fill
填充就行了,不过需要注意的是这里填充稍微麻烦一点,渐变不能像 CSS 那样,必须使用专门的渐变标签 <linearGradient>
,有兴趣的可以查看 linearGradient - SVG | MDN (mozilla.org),需定义在 <defs></defs>
中
<svg> <defs> <linearGradient id="gradient"> <stop offset="0%" stop-color="#FFCF02"/> <stop offset="100%" stop-color="#FF7352"/> </linearGradient> </defs> <text class="text">为你定制 发现精彩</text> </svg>
<linearGradient>
中的 <stop>
标签用来定义渐变的颜色坡度,offset
和 stop-color
分别定义渐变的节点和颜色,然后通过 fill
属性填充渐变(指明 id )
.text{ fill: url(#gradient); }
效果如下(并不是图片加载有问题哦)
这样下来有两个问题
文本水平方向和垂直方向都不居中
渐变方向是水平向右的
首先看第一个问题。SVG 中对文字的自适应处理还是非常弱的,比如 CSS 中常见的自动换行 SVG 中只能手动在指定位置换行。这里居中需要用到两个属性 text-anchor
和dominant-baseline
,分别标文本锚点对齐和文本基线对齐,简单来说就是水平和垂直方向的对齐方式
.text{ text-anchor: middle; dominant-baseline: middle; fill: url(#gradient); }
同时 <text>
还需要设置 x
、y
位置,这里的百分比可以和 CSS 中的背景位置百分比做类比
<text class="text" x="50%" y="50%">为你定制 发现精彩</text>
这样就居中显示了
关于渐变方向的问题,SVG 中是用x1
、y1
、x2
、y2
两组坐标来确定的。给定一个矩形,左上角是 [0,0]
,右下角是 [1, 1]
,这样任意角度都可以表示出来了
比如现在需要垂直向下方向的,那么可以在<linearGradient>
设置 x1="0" y1="0" x2="0" y2="1"
<svg> <defs> <linearGradient id="gradient" x1="0" y1="0" x2="0" y2="1"> <stop offset="0%" stop-color="#FFCF02"/> <stop offset="100%" stop-color="#FF7352"/> </linearGradient> </defs> <text class="text">为你定制 发现精彩</text> </svg>
.text{ -webkit-text-stroke: 2px #333; }
를 사용하세요. color
및 -webkit-text-fill-color
를 구현할 수 있습니다. 🎜<p class="text" data-title="为你定制 发现精彩">为你定制 发现精彩</p>
.text::before{ content: attr(data-title); position: absolute; background-image: linear-gradient(#FFCF02, #FF7352); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; -webkit-text-stroke: 0; } .text{ -webkit-text-stroke: 6px #333; }
fill
을 통해 직접 채우면 됩니다. 좀 더 번거롭습니다. Gradient CSS와는 달리 특수 Gradient 태그 <linearGradient>
를 사용해야 합니다. 관심 있는 분은 linearGradient - SVG | MDN(mozilla.org)은 <에 정의되어야 합니다. ;defs> 🎜.text{
/*其他*/
stroke-width: 4px;
stroke: #333;
}
로그인 후 복사로그인 후 복사🎜<linearGradient>
의 <stop>
태그는 그라디언트의 색상 경사를 정의하는 데 사용됩니다. code>offset
및 stop-color
는 각각 그라디언트 노드와 색상을 정의한 다음 fill
속성으로 그라디언트를 채웁니다(id 지정)🎜.text{ /*其他*/ stroke-width: 4px; stroke: #333; paint-order: stroke; /*先描边*/ }
text-anchor
및 dominant-baseline
이 필요합니다. 이 속성은 각각 텍스트 앵커 정렬과 텍스트 기준선 정렬을 표시하며 간단히 말해서 가로 및 세로입니다. 정렬 🎜.text{ /*其他*/ stroke-width: 4px; stroke: #333; paint-order: stroke; /*先描边*/ stroke-linejoin: round; /*路径转角为圆角*/ }
<text>
도 x
및 y
위치를 설정해야 합니다. 여기서 백분율은 다음과 같습니다. CSS의 배경 위치 비율과 동일합니다.🎜.text{ -webkit-text-stroke: 6px #333; text-shadow: 0 4px 0 #333; }
x1
, y1
, 를 사용합니다. >x2
및 y2
두 세트의 좌표로 결정됩니다. 직사각형의 경우 왼쪽 위가 [0, 0]
, 오른쪽 아래가 [1, 1]
이므로 어떤 각도라도 표현할 수 있습니다🎜🎜< img src ="https://img.php.cn/upload/image/646/846/371/163271294789478텍스트에 그라데이션, 획, 그림자 효과를 추가하는 두 가지 방법(CSS 및 SVG)" title="163271294789478텍스트에 그라데이션, 획, 그림자 효과를 추가하는 두 가지 방법(CSS 및 SVG)" alt="텍스트에 그라데이션, 획, 그림자 효과를 추가하는 두 가지 방법(CSS 및 SVG)"/>🎜🎜예를 들어 지금 수직 아래쪽 방향으로 가야 한다면 <linearGradient>
x1="0" y1="0" x2="0" y2="1"를 설정할 수 있습니다. >, 이렇습니다 🎜.text{ -webkit-text-stroke: 6px #333; filter: drop-shadow(0 4px 0 #333); }
CSS 中有个专门用于文字描边的属性 -webkit-text-stroke
,可以控制描边的宽度和颜色,比如
.text{ -webkit-text-stroke: 2px #333; }
效果如下
确实有描边了,但是文字好像瘦了一圈,如果觉得不太明显,可以再设置大一点
从这里可以看出,-webkit-text-stroke
其实是 居中描边,并且是覆盖在文本上的,也无法更改描边方式。而事实上,很多设计工具都是可以选择描边方式的,比如 figma
那么,如何实现外描边效果呢?
也是可以的!用两层文本,一层文本描边,一层文本渐变就可以了,为了节省标签,可以用伪元素来生成
<p class="text" data-title="为你定制 发现精彩">为你定制 发现精彩</p>
::before
设置渐变,位于上方,原文本设置描边,位于下方,注意把 ::before
的-webkit-text-stroke
去除
.text::before{ content: attr(data-title); position: absolute; background-image: linear-gradient(#FFCF02, #FF7352); background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; -webkit-text-stroke: 0; } .text{ -webkit-text-stroke: 6px #333; }
叠加示意如下
改变不同的描边也不会出现文字“变瘦”的情况
SVG 也可以实现描边效果,和 CSS 比较类似,应该说 CSS 是借鉴 SVG 的,通过 stroke
和 stroke-width
来控制描边颜色和大小,比如
.text{ /*其他*/ stroke-width: 4px; stroke: #333; }
可以得到这样的效果
和 CSS 表现一样,都是居中描边,也无法改变。
不一样的是,SVG 控制更为灵活,默认是先填充、然后再描边,所以看着是描边在填充之上,但是,我们可以改变这种规则,设置先描边,再填充,那么填充的颜色就会覆盖在描边之上了。SVG 中改变这种规则的可以通过 paint-order 来设置,关于这个属性,有兴趣的可以访问张鑫旭老师的这篇文章:CSS paint-order祝大家元旦快乐
.text{ /*其他*/ stroke-width: 4px; stroke: #333; paint-order: stroke; /*先描边*/ }
这样就实现了外描边效果,是不是比 CSS 方便许多?
除此之外,SVG 还可以设置描边路径的转角处的形状,比如 figma 中关于转角的设置如下
SVG 中与之相对应的属性叫做 stroke-linejoin,这里是圆角,可以做如下设置
.text{ /*其他*/ stroke-width: 4px; stroke: #333; paint-order: stroke; /*先描边*/ stroke-linejoin: round; /*路径转角为圆角*/ }
各种属性效果如下
继续添加效果。CSS 可以通过 text-shadow
来添加文本投影
.text{ -webkit-text-stroke: 6px #333; text-shadow: 0 4px 0 #333; }
结果变成了这样
原因其实还和文本渐变有关,渐变其实是背景色,文字是透明的,所以给文字添加阴影,结果阴影就覆盖在了背景之上。除了使用text-shadow
,还可以通过 drop-shadow
滤镜实现
.text{ -webkit-text-stroke: 6px #333; filter: drop-shadow(0 4px 0 #333); }
这样就完美实现了
SVG 就比较灵活了,比如上面使用的 drop-shadow
滤镜,其实就是借鉴了 SVG 中的 滤镜,所以 SVG 也可以这样实现
<svg> <defs> <linearGradient id="gradient" x1="0" y1="0" x2="0" y2="1"> <stop offset="0%" stop-color="#FFCF02"/> <stop offset="100%" stop-color="#FF7352"/> </linearGradient> <filter id="shadow"> <feDropShadow dx="0" dy="4" stdDeviation="0" flood-color="#333"/> </filter> </defs> <text x="50%" y="50%" class="text">为你定制 发现精彩</text> </svg>
这里dx
、dy
、stdDeviation
、flood-color
和 drop-shadow(dx,dy,stdDeviation,flood-color)
中的参数是一一对应的,就不多说明了,然后在文字中应用滤镜
.text{ /*其他*/ filter:url(#shadow); }
这样也能实现文字投影
其实 SVG 中大可不必这么麻烦,刚才上面 text-shadow
之所以不能使用,就是因为 CSS 实现的文字渐变是背景,是假的文字渐变,但是 SVG 中是真真正正的渐变填充,所以没错,这里可以直接用 CSS 中的 text-shadow
来实现,SVG 和 CSS 现在很多属性和样式都互通了,如下
.text{ /*其他*/ fill: url(#gradient); text-shadow: 0 4px 0 #333; }
实现更加简洁
通常活动标题会采用一些特殊的字体,英文字体还好,整个引入都可以,但是中文就不行了,大多数中文字体都非常大,可能达到几十MB或者几百MB。其实我们只需要用到出现的字体,如果把出现的文字这一部分的特殊字体单独提取出来,那么整个字体文件将大大减小,这个过程就叫做字体子集化。
那么该如何处理呢?
这里推荐一个工具 Fontmin - 字体子集化方案,关于字体子集化的原理,可以参考这篇文章:性能优化魔法师:中文字体实践篇 - 掘金
下载客户端后,导入字体文件.ttf
,然后输入需要用到的文字,如下
点击生成,可以得到如下文件
其中第一个以-embed
为后缀的 CSS,里面是转换 base64 后的文件,可以直接引入
@font-face { font-family: "HYLiLiangHeiJ Regular"; src: url("HYLiLiangHeiJ Regular.eot"); /* IE9 */ src: url("HYLiLiangHeiJ Regular.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */ url(data:application/x-font-ttf;charset=utf-8;base64,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) format("truetype"), /* chrome、firefox、opera、Safari, Android, iOS 4.2+ */ url("HYLiLiangHeiJ Regular.svg#HYLiLiangHeiJ Regular") format("svg"); /* iOS 4.1- */ font-style: normal; font-weight: normal; } .text{ /*其他样式*/ font-family: "HYLiLiangHeiJ Regular"; }
这样几乎实现了和设计稿完全一致的效果
其实如果从头看下来,应该也能自己实现一个,既能掌握原理,也能加深印象,完全变成自己的了。不过可能不是每个同学都有时间,或者能够静下心来研究每一个案例,所以这里还是整理了一下在线 demo,想要快速看结果的直接访问就行了,如下
CSS 实现可以访问 text-css (codepen.io)
SVG 实现可以访问 text-svg (codepen.io)
以上介绍了 CSS 和 SVG 两种不同的方式来实现文本的特殊效果,从效果来看,显然 SVG 要更胜一筹,比如描边更加平滑、也无需多层嵌套,但 CSS 也有优势,比如渐变色和投影更加简单,总结一下
CSS 文字渐变本质是背景裁剪,需要将文字颜色设为透明
SVG 文字天然支持渐变填充,需要借助 linearGradient 标签
SVG 文本居中稍微麻烦点,需要借助 text-anchor 和 dominant-baseline
CSS 및 SVG 스트로크는 모두 중앙에 있는 스트로크이며 변경할 수 없습니다.
CSS 외부 스트로크는 다층 구조 오버레이를 통해 구현할 수 있습니다.
SVG는 페인트 순서를 통해 스트로크 위에 채울 수 있습니다.
CSS 텍스트 그림자는 텍스트가 투명할 때 침투하므로 그림자를 사용하여 그림자를 시뮬레이션할 수 있습니다.
SVG의 feDropShadow는 CSS의 그림자와 유사합니다.
SVG는 CSS 텍스트에서 직접 사용할 수 있습니다. -shadow는 텍스트 프로젝션을 구현합니다
font subsetfontmin
CSS와 SVG는 서로 장점이 있고 서로 영향을 미칩니다. 많은 CSS 스타일도 SVG에서 사용할 수 있으며 많은 SVG 속성도 CSS에 도입되기 시작했습니다. .평상시에는 개발 과정에서 두 가지의 장점이 완전히 결합될 수 있습니다.
더 많은 프로그래밍 관련 지식을 보려면 프로그래밍 비디오를 방문하세요! !
위 내용은 텍스트에 그라데이션, 획, 그림자 효과를 추가하는 두 가지 방법(CSS 및 SVG)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!