转载

CSS vs. SVG:图形文本的效果

这篇文章是探索有关于CSS和SVG技术的系列文章第一篇,通过例子来阐述CSS和SVG相关技术的比较。因为大家对SVG有一定的偏见,这个系列文章只是为了证明SVG解决Web上的某些设计问题。因为它是自然图像。但从客观的角度来看,我们要考虑每个技术的利弊,找出何时何地使用CSS或SVG更好。

在这篇文章中,我们将复习一些使用CSS或SVG创建图形文本的技术和相关影响。

CSS创建的图形文本

老的CSS方法

几年前,我们要在网页上创建吸引人的文本视觉效果,需要通过图像替换文本的方案,否则是无法实现想要的图形文本。

这是显示图像文本的概念,文本在屏幕上可能显示出较好的一个效果。当我们没有实现它的时候,屏幕上就会显示文本,这个效果也不错。我们把实现它的技术称为 图像替换文本 技术。

假设你想在 <h1> 标题上通过吸引人注意力的图像来显示相同的文本,你会使用类似下面的CSS:

h1.hide-text {  text-indent: 100%;  white-space: nowrap;  overflow: hidden;  background-image: url(…); }  

通过文本缩进确保标题的内容超过自己的边界溢出,并且通过 overflow:hidden 将溢出的文本隐藏起来,保证溢出的标题文本不显示出来。所以你最终看到的矩形区域( <h1> )内没有文本显示。

然后标题区域将显示出你在图形编辑器(例如Photoshop)创建的图形文本。

所以,显示在屏幕上标题矩形区域,里面没有文本内容,通过背景图像显示图形文本。所以你需要做的是制作效果不错的图形文本。

自从Kellum提出这个方案后没有更好的解决方案提供给开发人员使用,所以把上面的这种方法称为 Kellum方法 。事实上, 有不少图像替代文本技术 ,但是Kellum方法取代了他们中的大多数方法,因为它是“最好”的选项。

这种技术是一种Hack手段,致使用户不能选择文本(因为它是运用在背景中的图形文本),接下来介绍的新的属性可以达到类似的效果,并且不需要使用图像替换文本技术。

新的CSS方法

@Lucas Bebber 在Dreamweaver的 博客 中写了一篇《 squiggly text effects 》文章,有很多创建图形文本的效果,包括一些弯弯曲曲的文本效果。最常见的文本效果是 纹理填充 的文本效果或简单的纹理混合文本的效果,看起来像是一张背景图像。

纹理填充文本

CSS vs. SVG:图形文本的效果

使用CSS的 background-clip 属性,可以将背景图像填充到文本。这个属性决定了元素的背景区域,其默认值是 border-box ,背景会延伸到元素的边框边界,但可以将其值设置为 padding-boxcontent-box ,将背景延伸到内距边界或内容边界。

在Webkit内核中对 background-clip 有一个 扩展值 ,那就是 text ,使用背景根据文本进行裁剪。然后通过Webkit给文本自定的私有属性 -webkit-text-fill-color ,并且设置其值为 transparent ,背景图像就会显示在文本中,从而完成了剪切效果。

例如,将一个元素的背景图像在其文本内显示,可以给元素定义一个类名,然后运用这些样式:

.clippedElement {  /* background image that will serve as text fill */  background: url(path/to/your/image.jpg) no-repeat center center;  /* -webkit-background-clip clips the background of the element to the text */  -webkit-text-fill-color: transparent; /* overrides the white text color in webkit browsers */  -webkit-background-clip: text;  /* general styles */  background-size: 100% auto;  color: #fff;  text-align: center;  padding: 2em; }  

正如你看到的,属性前面使用的前缀,你就不难发现,这个效果只有在Webkit内核的浏览器才能看到效果,而在Firefox和IE浏览器中是看不到效果的。

回到前面所说的 <h1> 标题上,给他设置一个背景,在页面上就可以不需要隐藏文本也能看到文本填充效果。还有一个替代方案,将标题放在一个 div 内,并且把需要填充到文本的图像设置为这个 div 的背景图像,使用上面的CSS样式就能实现图像文本。

下面这个示例演示的技术,确保你在Chrome、Safari和Opera浏览器都能看到效果:

对于不支持的浏览器,你可以看到一个简单的效果,就是文本的图像之上,只要你确保文本与背景图像的颜色有区别,就不会引起任何阅读上的问题。

注意,背景图像可以是任何图像,包括CSS的渐变,因为CSS的渐变也是一个背景图像。你可以从这里了解CSS渐变的所有知识点。

纹理填充文本(使用CSS混合模式)

接下来,我们将使用CSS的 mask 技术创建下图的文本效果,文本看上去有一部被抹掉了:

CSS vs. SVG:图形文本的效果

当使用CSS的 mask 时,图像文本是带了一个蒙板,而不是图像的形状(或被剪切的形状)。

上面显示的效果使用了图片来做蒙板,一年前我在 Codrops 上写过一篇有关于这方面的 文章 。图像做为一个蒙板,将文本区域下的背景展示出来。如果选择合适的蒙板图片与背景,可以得到一个无缝融合的效果。我们使用了一张油漆四溅的图像做为蒙板。为了简单起见,其自身不做任何的图层混合模式处理,只将纹理应用到文本上。

CSS vs. SVG:图形文本的效果

蒙板图像可以是任何你想要的图像,包括渐变做的渐变效果。

当你把CSS的 mask 运用到文本上或任何其他的内容时,黑色区域的文本是可见的,蒙板图像透明部分的文本是不会显示。这是因为蒙板图像在CSS中使用时,默认是一个透明通道,而不是一个亮度蒙板,这样就造成了蒙板黑色区域的文本显示出来。

对于渐变做为蒙板图像的情况时,是从黑色过渡到透明。例如,蒙板元素将是完全不透明的黑色,逐渐变得半透明,然后慢慢的变得透明。

使用CSS的 mask-image 将蒙板图像用在适当的文本之上:

h1 {     /* the line that applies the splatter effect */     mask-image: url(../img/splatter-mask_1.png);       /* any general styles go here like font family, alignment, etc. */ } 

在写这篇文章之时,CSS的 mask 属性支持度不是很好。Firefox浏览器只支持SVG的蒙板,而Webkit浏览器需要添加浏览器的私有前缀 -webkit 。有关于 mask 属性的浏览器兼容性,可以查看下表:

这是另一种实现纹理文本的方法,但也是不可靠。下面这个示例演示了这个效果,请使用Webkit内核浏览器查看:

如果你想使用渐变做为蒙板图像,可以使用下面的代码替换 mask-image 的值:

mask-image: linear-gradient(black, transparent); 

这样能看到一个文本淡出的效果。这就是如何在一个元素或文本上使用CSS实现纹理的方法。随着SVG的出现,我们或许可以找到更好的方案。

使用SVG实现图像文本

SVG太棒了。(我不得不这么说。)现在,为了简单起见,我们将使用代码来解释这一切。

在使用SVG时,文本和效果都将定义在一个 <svg> 元素内。

纹理填充文本

制作一个带纹理的文本,首要的就是先定认一个纹理,然后选择你喜欢的颜色填充到元素上。在我们的案例中,SVG是一段文本。

对于本例,我们将定义一个线性渐变,并将其运用到一个文本上。

CSS vs. SVG:图形文本的效果

代码看起来像这样:

<svg xmlns=“http://www.w3.org/2000/svg”  viewBox=“0 0 1250 400” width=“1250” height=“400”>      <title>Gradient-filled Text</title>     <!— Source: http://lea.verou.me/2012/05/text-masking-the-standards-way/ —>     <defs>        <linearGradient id=“filler” x=“0%” y=“100%”>            <stop stop-color=“gold” offset=“0%”></stop>              <stop stop-color=“purple” offset=“20%”></stop>            <stop stop-color=“deepPink” offset=“40%”></stop>            <stop stop-color=“orange” offset=“60%”></stop>            <stop stop-color=“yellow” offset=“80%”></stop>            <stop stop-color=“skyblue” offset=“100%”></stop>       </linearGradient>     </defs>     <text x=“100” y=“70%” font-size=“205” fill=“url(#filler)”> Radiant Text</text> </svg> 

注意:我们给 svg 指定了一个高度和宽度,但是为了确保 svg 是弹性的,可以使用CSS的百分比做为单位来覆盖默认的尺寸。如果你感兴趣,可以 点击这里 学习如何实现响应式设计的SVG。

在这个示例中使用 linearGradient<def> 元素定义需要的纹理,同时给这个渐变 linearGradient 设置一个 #id ,然后通过 fill 属性将渐变纹理用在 <text> 元素上。这样是不是更具语义呢?

这是上面代码的效果:

纹理可以是任何东西,哪怕是SVG的 <image> 元素引用的外部图像(JPEG、PNG和GIF图像等)。它也可以是一个SVG的 <pattern> 元素。

因为SVG是一个图形,为了方便屏幕阅读器能读到,一定要给其定义一个 title<svg> 中的这个 title 就相当于 <img> 元素的 alt 属性。

背景纹理填充文本(使用混合模式)

类似前面的技术,将CSS的 mask 和SVG的 <def> 结合起来,可以将纹理填充到SVG的 <text> 元素上。在填充之前,首先要做的是定义一个纹理。在SVG中可以使用 <mask> 定义纹理,并且在 <text> 元素上使用 mask 属性替代 fill 属性,将 <mask> 定义的纹理填充到文本中。

在下面这个示例中,我们制作了一个类似于被咬过的文本效果,如下图所示:

CSS vs. SVG:图形文本的效果

使用SVG制作一个咬痕的纹理,并且应用到一个文本之上。

首先通过图形编辑器制作一个咬痕的纹理,为了达到需要的效果,先在文本上添加需要的效果。它助于你在想要的地方得到你需要的效果。

然后,将图形导出成SVG,并且将图形的蒙板放在 <def> 元素内,导出的代码如下所示:

<svg viewBox=“0 0 900 400”>   <defs>     <mask id=“mask”>  <rect x=“0” y=“0” width=“100%” height=“100%” fill=“#fff”></rect>   <path fill=“#000” d=“…”></path>   <path fill=“#000” d=“…”></path>   <path fill=“#000” d=“…”></path>   <path fill=“#000” d=“…”></path>   <path fill=“#000” d=“…”></path>   <path fill=“#000” d=“…”></path>   <path fill=“#000” d=“…“></path>   <path fill=“#000” d=“…“></path>     </mask>   </defs>   <text font-size=“230” fill=“#FF481E” mask=“url(#mask)”>     <tspan x=“0” y=“150”>nom</tspan>     <tspan y=“280” x=“150”>nom<tspan>     <tspan y=“400” x=“350”>nom<tspan>   </text> </svg>  

有一点需要特别的注意: 在SVG中不像CSS的,蒙板元素需要填充白色,而不是黑色。 黑色和白色之间的任何值都将呈现为半透明状态,如此一来,元素越接白色( #ffffff ),蒙板越不透明,蒙板的颜色越接近黑色( #000000 ),越接近透明。

因此,在上面的例子中,给咬过的形状填充为黑色,而整个SVG元素填充的是白色,这是为了确保文本在画布的任何地方都可以显示,除了黑色的咬痕之处不显示。

上面的示例代码,在浏览器上的效果看起来像这样:

这里你要做的仅是在SVG中将需要的纹理填充到文本上。你可以使用一个渐变、图像或其他任何形状或模式来填充你的文本。在 <def> 元素上你有很多的选择项,也可以创建很多有趣的效果,比如动画纹理填充。

使用SVG制作动画纹理填充

SVG不仅为我们提供更好的支持和模块化(因为文本和其效果都包装在一起),而且SVG还可以实现动画效果。

在SVG的 <def> 元素内,你可以给其定义一个填充( fill )时,也可以使用动画填充。这意味着,你将可以实现类似下图的一些动画纹理填充文本的效果:

CSS vs. SVG:图形文本的效果

在上面的示例中,有一个是使用了GIF动画图片做的填充,所以在文本的填充里也保持了GIF动画效果。

在 Codrops 我写过 一篇文章 ,主要阐述的就是如何使用SVG给文本创建动画纹理,如果你想了解更多的细节,可以仔细 阅读这篇文章 。

总结

直到浏览器全面支持CSS的 background-clip:text 属性之前,SVG绝对是创建纹理填充文本效果的最佳方法。

事实上,我个人仍然喜欢使用SVG创建动画,虽然CSS中有更好的动画功能。我喜欢这个的原因是,SVG可以将文本和效果封装为一个图形,这样可以复制,也可以降级处理,更可以重用。更为重要的是,SVG的更具可读性,更具语义,也可以完全选择。

请持续关注CSS和SVG技术的比较,在下一篇文章中将继续为大家阐述相关的技术,通过这些示例的比较,更好的帮助大家做出更好的选择,决定选择哪一种技术。

本文根据 @Sara Soueidan 的《 CSS vs. SVG: Graphical Text Effects 》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处: https://blogs.adobe.com/dreamweaver/2015/07/css-vs-svg-graphical-text.html 。

CSS vs. SVG:图形文本的效果

大漠

常用昵称“大漠”,W3CPlus, Sass中国 创始人,目前就职于手淘。中国Drupal社区核心成员之一。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。

正文到此结束
Loading...