β

【译】用css定义svg的样式和动画

携程UED 291 阅读

原文: http://www.smashingmagazine.com/2014/11/03/styling-and-animating-svgs-with-css/
翻译: 叮当当咚当当小胖妞呀 杀手爱elva Ivan_z3 肖弦

CSS可以用来定义可缩放矢量图形的样式和动画,就像CSS定义HTML元素一样。在本文中,我会告诉大家一些用CSS定义SVG的前提条件和技术。(我最近在 CSSconf EU From the Front 办了一个 讲座 ,这篇文章是讲座的修正版)

同时我也会讲一下导出和优化SVG、嵌入SVG和每一个SVG如何影响它的样式和动画,然后我们再讨论用CSS定义SVG的样式和动画。

介绍

可缩放矢量图形(SVG)是基于可扩展标记语言(XML),用于描述二维矢量图形的一种图形格式,它们支持交互行为和动画。换句话说,SVG是可以生成形状和图形的XML标签,这些形状和图形可以像HTML元素一样实现交互和动画。

我们可以通过CSS或者Javascript给SVG定义动画和交互行为。在本文中,我们着重讨论CSS。

SVG为什么好?为什么你应该使用它?其实答案有很多:

从图形编辑器导出SVG并优化

以下是三个最流行的矢量图形编辑器:

  1. Adobe Illustrator ,
  2. Inkscape ,
  3. Sketch

Adobe Illustrator是Adobe公司收费的应用程序,它是最受欢迎的编辑器,漂亮的UI和大量的功能使得它成为大多数设计师最喜欢的编辑器。

Inkscape是另一个免费的编辑器,虽然它的UI没有Illustrator漂亮,但是它仍然具有你所需要的所有功能。

Sketch是只能在Mac OS X上使用的app,虽然它也要收费,但是它在设计师中 到处宣传 收到了欢迎 ,最近Sketch又推出了许多 资源和工具 来改善工作流程。

你可以选择任意编辑器来创建你的SVG。在选择编辑器、创建SVG之后,在把它嵌入网页之前,你需要把它从编辑器中导出并进行清理。

我会导出并优化在Illustrator中创建的SVG,除了Illustrator特定的一些选项,其余步骤跟任何编辑器都基本一致。

如果要从Illustrator中导出SVG,你需要选择“File” -> “Save as”,然后从文件扩展名下拉菜单中选择“.svg”。一旦你选择了.svg扩展名,会出现一系列导出SVG的选项面板,比如使用哪个版本的SVG、是否在图形中插入图片或者在外部保存并把它们链入SVG、如何为SVG添加样式(使用展示属性或者使用CSS的 style 标签)。

下图展示了导出SVG的最佳设置:

导出SVG的最佳设置

上图中选项是最佳设置的原因可以参考Michaël Chaize的文章: 使用Illustrator CC导出SVG

无论你使用哪种图形编辑器,输出的都不会是优化的代码。SVG文件,尤其是从编辑器导出的文件,通常包含了很多多余信息,比如编辑器的meta信息、注释、空白的组、默认值、非优值等,这些信息可以被安全的移除或者转换,而不会影响SVG的生成。如果你在使用不是你自己创建的SVG文件,那么代码基本上都是非优的,所以我们推荐使用独立的优化工具优化它。

这里有些优化SVG代码的工具。Peter Collingridge的 SVG编辑器 是一款在线的工具,你可以直接输入SVG代码,或者上传SVG文件,然后它会提供一些优化的选项,如移除多余代码、注释、空白组、空格等等。其中有一个选项可以让你指定点坐标小数的位数。

SVG编辑器

Peter的优化工具也可以自动把inline SVG属性移动到文档头部的 style 标签中去,这个工具最好的地方在于,当你点击某个选项之后,你能实时看到优化的结果,这样你就可以自主决定使用哪种方法优化。某些特定优化可能会 损坏 你的SVG。比如,通常一位小数 应该 足够了,但是当你在使用一个路径繁多的SVG文件时,如果把小数的位数从四削减到一,你的文件会小掉一半,但是你的SVG也会损坏,所以能够预览优化也是一个很棒的加分点。

Peter的工具是在线的,如果你喜欢使用离线工具,你可以尝试 SVGO (其中的“O”是“Optimizer”的缩写),这是一个基于Node.js的工具,它有一个漂亮并简易的 拖放GUI 。如果你不想要使用在线工具,它会是一个很好的选择。

下面的截图是用Peter的优化工具优化之前和之后的SVG代码:

优化之前和之后的SVG代码

我们可以看到原始文件和优化文件大小的变化,此外优化的文件更具可读性。

在优化SVG之后,可以把它嵌入web页面,之后用CSS自定义或动画。

用CSS定义SVG样式

HTML和CSS之间的界线很明确:HTML是内容和结构,CSS是样子。而SVG却模糊了这条界线。SVG 1.1不要求使用CSS定义SVG标签的样式——样式是通过“展示属性(presentation attribute)”应用到SVG元素中去的。

展示属性是在元素中设置CSS属性的简写,可以把它们看成一种特殊的样式属性。

下面的例子是使用展示属性为一个星形多边形定义边框样式( stroke )和背景颜色( fill ):

fill stroke stroke-width 属性都是展示属性。

在SVG中,CSS属性的子集可能是SVG属性,反之亦然。SVG规范 罗列了一些可能被设定为CSS属性的SVG属性 ,其中一些属性和CSS共用,如 opacity transform 等,其他一些不是,如 fill stroke stroke-width 等。

在SVG2中,这个列表包含 x y width height cx cy 和一些其他的展示属性,这些属性不能在SVG 1.1中通过CSS设置。我们可以在 SVG 2规范 中找到这些新属性。

另一个设置SVG元素样式的方法是使用CSS属性。就像在HTML中一样,样式可以用inline样式属性设置到元素中去:

样式也可以使用 style 标签定义, style 标签可以放在 svg 标签中:

html
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300px" height="300px" viewBox="0 0 300 300">
  <style type="text/css">
  <![CDATA[
  selector {/* styles */}
  ]]>
  </style>
  <g id=".."> … </g>
</svg>

你也可以把它放在 svg 标签外:

html
<!DOCTYPE html><!-- HTML5 document -->
<html>
<head> … </head>
<body>
    <style type="text/css">
    /* style rules */
    </style>
    <!-- xmlns is optional in an HTML5 document →
    <svg viewBox="0 0 300 300">
    <!-- SVG content -->
    </svg>
</body>
</html>

如果你想要把svg跟标签完全分开,你可以使用 <?xml stylesheet> 标签链入外部样式表,代码如下:

html
<?xml version="1.0" standalone="no"?>
<?xml-stylesheet type="text/css" href="http://ued.ctrip.com/blog/style.css"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width=".." height=".." viewBox="..">
  <!-- SVG content -->
</svg>

样式层级

我们之前提到展示属性是一种特殊的样式属性,它们是在SVG节点上设置CSS属性的简写,正由于此,SVG展示属性也是样式层级的一种。

确实,展示属性只作为低端的“作者样式表”,它会被任何其他的样式定义所覆盖,如外部样式表、文档样式表和inline样式。

下面的图表向我们展示了样式的层级,下方的样式表会覆盖上方的样式表,你可以看到,展示属性样式会被其他所有的样式覆盖,除了客户端样式。

样式层级

例如,在下面的代码片段中描画了一个SVG圆形元素,圆形的填充颜色是深粉色,覆盖了展示属性中定义的蓝色:

html
<circle cx="100" cy="100" r="75" fill="blue" style="fill:deepPink;" />

选择器

大多数 CSS选择器可以用来选择SVG元素,除了一般类型的选择器:样式和ID选择器之外,SVG还可以使用CSS2的 动态伪类选择器 :hover :active :focus )和 伪元素 (例如 :first-child :visited :link :lang )。剩下的CSS2伪元素,包括 生成内容 的选择器(例如 ::before ::after )不在SVG的定义中,因此对SVG样式无效。

下面是一个简单的动画代码,一个深粉色的圆形,在hover的时候逐渐变成绿色:


circle {
   fill: deepPink;
   transition: fill .3s ease-out;
}
circle:hover {
   fill: #009966;
}   

我们还可以创造许多更震撼的效果, Iconic 有一个很简单但是很棒的效果,当我们hover在的灯泡上时会点亮灯泡,我们可以看一下这个 demo

注意事项

由于展示属性是用XML属性表达的,所以它们对大小写敏感,例如,当我们要定义元素的填充颜色时,属性必须写成 fill = "..." ,而不能写成 Fill = "..."

此外,这些属性的值(例如 font-style = "italic" 中的 italic )也是大小写敏感的,必须按照规范定义中的格式书写。

其他所有以CSS属性定义的样式——无论是inline样式,还是在 <style> 标签中,或是在外部样式表中——都是以CSS规范的语法规则定义的,通常它们对大小写不敏感。话虽如此, SVG”样式” 规范建议我们完全按照CSS规范中定义的属性名称书写,并使用同一种书写规范(通常我们使用小写字母和中划线),不要利用CSS忽略大小写的特点任意书写。

用CSS制作SVG动画

SVG可以做到像HTML元素一样,用CSS keyframe、animation属性或者CSS transition制作动画。

多数情况下,复杂的动画效果通常包含了一些变换,有translate、rotate、scale和skewing。

在大多数情况下,SVG元素和HTML元素对于 transform transform-origin 的解读是一样的,然而还是会有一些不可避免的差异。和HTML元素不同的是,SVG元素不会被盒模型所局限,因此它就不会有margin、border、padding以及content boxes。

对于HTML元素来说,transform的原点默认是 (50%,50%) ,也就是元素的中心。然而,SVG元素transform的原点默认是用户当前的坐标系统,也就是 (0, 0) ,在canvas的左上角。

假设这里有一个html元素 <div> 和一个SVG元素 <rect>

html
<!DOCTYPE html>
    …
    <div style="width: 100px; height: 100px; background-color: orange"> </div>
    <svg style="width: 150px; height: 150px; background-color: #eee">
        <rect width="100" height="100" x="25" y="25" fill="orange" />
    </svg>

如果不改变它们的transform原点,让它们都旋转45度,我们可以得到如图结果(红色的小原点就是它们transform原点所在位置):

transform-origin

如果想让SVG元素在旋转的时候绕着它自己的中心,而不是SVG canvas的左上角,应该怎么做呢?我们需要明确地设置 transform-origin 属性来确定transform原点。

如何设置transform原点是很明确的:你设置的值与元素的border box模型相关。

在SVG中,transform原点的值可以是一个百分数或者绝对的数值(比如像素)。如果transform-origin的值是百分数,那么它的位置就和元素的边界框有关。如果它的值是一个绝对的数值,它的位置就和SVG canvas上用户的当前坐标系统有关。

我们把 <div> <rect> 的transform origin值设为百分数,就像这样:

html
<!DOCTYPE html>
    <style>
        div,rect {
        transform-origin: 50% 50%;
        }
    </style>

那么最终的变换效果是这样的:

transform-origin

话虽如此,在撰写本文的时候,Firefox还无法支持值为百分比的写法。这是一个大家 熟知的bug ,因此最好还是使用绝对数值,我们肯定能得到所期待的效果。当然你依然可以选择在WebKit浏览器上使用百分数值。

在接下来的例子中,我们会使用CSS animation来实现风车效果。为了使风车绕着自己的中心旋转,我们会用像素和百分比来设置它的transform origin。

html
    <svg>
    <style>
    .wheel {
        transform-origin: 193px 164px;
        -webkit-transform-origin: 50% 50%;
        -webkit-animation: rotate 4s cubic-bezier(.49,.05,.32,1.04) infinite alternate;
        animation: rotate 4s cubic-bezier(.49,.05,.32,1.04) infinite alternate;
    }

    @-webkit-keyframes rotate {
% {
        -webkit-transform: rotate(360deg);
        }
    }

    @keyframes rotate {
% {
        transform: rotate(360deg);
        }
    }

    </style>
    <!-- SVG content -->
    </svg>

你可以 查看Codepen上的效果 。这里要注意的是,在撰写此文的时候,SVG元素上的CSS 3D transformation还 不能 使用硬件加速,所以3D的效果跟2D完全一样,然而,Firefox已经 能够 一定程度上提升transform的速度。

为SVG路径添加动画

现在还无法用CSS animation将SVG路径从一个形状改变成另外一个形状。如果你想要 改变 路径,也就是从一个动画过渡到另一个路径,必须要用到JavaScript。如果你想要实现这样的效果,我建议你使用Dmitry Baranovskiy写的 Snap.svg ,他还写了SVG Library Raphaël

Snap.svg相对于SVG的地位就好像jQuery相对HTML的地位一样,它能让我们更简单的处理SVG的一些特殊情况。

虽然不能用CSS改变形状,但是你却可以用CSS来创建一个动态的画线效果。使用animation的时候,你必须要先设定线条路径的总长度,然后用SVG的 stroke-dashoffset stroke-dasharray 属性实现画画效果。一旦你知道路径长度,就可以通过下面的方法来实现动画了:

css
#path {
    stroke-dasharray: pathLength;
    stroke-dashoffset: pathLength;
    /* transition stroke-dashoffset */
    transition: stroke-dashoffset 2s linear;
}

svg:hover #path {
    stroke-dashoffset: 0;
}

在上面的例子中,当hover SVG时,图形路径会在2秒内画好。

在接下来的演示中,我们将会用到同样的原理,再加上CSS的transition延迟,让灯泡在路径动画完成时点亮。

css
#cable {
  stroke: #FFF2B1;
  stroke-dasharray: 4000 4000;  
  stroke-dashoffset: 4000;
  stroke-width: 4;
  transition: stroke-dashoffset 8s linear;
}

svg:hover #cable {
  stroke-dashoffset: 0;
}

/* turn lamp on */
.inner-lamp{
  fill:grey;
  transition: fill .5s ease-in 6s;
}

svg:hover .inner-lamp {
  fill: #FBFFF8;
}
/* … */

你可以在 JS Bin中查看demo ,提醒大家,你同样可以写成 stroke-dasharray: 4000 而不是 stroke-dasharray: 4000 4000 ——如果两个值相同,你可以只定义一个值。

有时候,可能你并不能知道动画路径的确切长度,这时,你可以用到JavaScript的 getTotalLength() 方法来获取。

js
var path = document.querySelector('.drawing-path');
path.getTotalLength();
//set CSS properties up
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length;
//set transition up
path.style.transition = 'stroke-dashoffset 2s ease-in-out';
// animate
path.style.strokeDashoffset = '0';

上面这个片段是一个非常简单的例子,它用JavaScript实现了我们之前用CSS达到的效果。

Jake Archibald针对此技术写了一篇详细的 文章 。Jake在文章里写了一个很棒的交互演示,展现了动画到底是如何实现的,以及这两个SVG属性如何共同实现我们想要的效果。如果你对这个技术感兴趣,我建议你读一下他的文章。

SVG的嵌入

一个SVG文件可以通过六种方法嵌入到文档中,每一种都有各自的优点和缺点。

我们讨论嵌入技术的原因是,你嵌入SVG的方法会影响到一些CSS样式、动画、交互是否会实现。

以下为SVG的嵌入方法:

  1. 作为图片使用 <img> 标签嵌入: <img src="http://ued.ctrip.com/blog/mySVG.svg" alt="" />
  2. 作为CSS中的背景图片嵌入: .el {background-image: url(mySVG.svg);}
  3. 作为对象使用 <object> 标签嵌入: <object type="image/svg+xml" data="mySVG.svg"><!-- fallback here --></object>
  4. 作为框架使用 <iframe> 标签嵌入: <iframe src="http://ued.ctrip.com/blog/mySVG.svg"><!-- fallback here →</iframe>
  5. 使用 <embed> 标签嵌入: <embed type="image/svg+xml" src="http://ued.ctrip.com/blog/mySVG.svg" />
  6. 行内使用 <svg> 标签嵌入: <svg version="1.1" xmlns="http://www.w3.org/2000/svg" …> <!-- svg content → </svg>

从引入外部SVG文件现在大部分都使用 <object> 标签,这个标签最大的好处是在SVG没有渲染的时候能够优雅降级,提供图片(或者文本)。当SVG因为某些原因没有加载时——比如提供的URI错误——浏览器就会展现 <object> 起始标签和结束标签里面的内容。

html
    <object type="image/svg+xml" data="mySVG.svg">
        <img src="http://ued.ctrip.com/blog/fallback-image.png" alt="…" />
    </object>

如果你想实现高级的SVG特效,比如CSS或者scripting,HTML5的 <object> 标签就是你最好的选择。

因为浏览器在用它们各自的方式渲染SVG文档,所以可以用iframe来完成嵌入和展现SVG。如果你想要完全将SVG代码和脚本在主页面中分离,这会是一个很好的方法。然而,用JavaScript控制SVG图片有点困难,并且同时还会受到 同源策略 的限制。

<iframe> 标签就像 <object> 一样,当浏览器不支持SVG或者因为某些原因无法渲染的时候会提供回退机制。

html
    <iframe src="http://ued.ctrip.com/blog/mySVG.svg">
        <img src="http://ued.ctrip.com/blog/fallback-image.png" alt="…" />
    </iframe>

<embed> 标签不是HTML规范的一部分,却仍然得到了广泛的支持,它用来囊括需要外部插件才能工作的内容。Adobe公司的Flash插件就需要用到 <embed> 标签,支持这个标签为唯一原因是为了使用SVG, <embed> 标签没有默认回退机制。

SVG也能使用 <svg> 标签inline嵌入到文档中——作为一个”代码块”,这是当下嵌入SVG最主流的方法之一。使用inline的SVG和CSS会比较容易,因为无论样式规则放置在页面的哪个位置都可以轻松定义SVG的样式和动画。也就是说,样式不需要包含在 <svg> 标签里,这对于其他技术来说这也是很必要的。

inline嵌入SVG是一个很好的选择,只要你愿意增加页面的尺寸,并且放弃它向下兼容性(因为它没有默认回退机制)。要注意的是,inline嵌入SVG不能缓存。

在定义CSS样式和动画的时候,用 <img> 标签和作为CSS背景图片嵌入SVG很类似。一旦嵌入了SVG,外链的CSS资源中的样式和动画不会被保留。

下面的表格展现了用六个不同的方法嵌入SVG时,CSS动画和交互(比如hover效果)是否会被保留。最后一列是将它与 SMIL animations 比较,无论哪种情况, SVG animations (SMIL) 都支持。

CSS交互 (例如:hover) CSS动画 SVG动画 (SMIL)
<img> 是 只在 <svg>
CSS背景图片 是 只在 <svg>
<object> 是 只在 <svg> 是 只在 <svg>
<iframe> 是 只在 <svg> 是 只在 <svg>
<embed> 是 只在 <svg> 是 只在 <svg>
<svg> (inline)

表格展示了当SVG嵌入时,CSS样式、动画和交互是否会被保留

以上表格中都是标准行为的,然而,在每个浏览器中实现效果可能有差异,也可能存在bug。

这里要注意的是,即使SMIL animations会被保留,但在SVG被当做图片嵌入的时候(比如 <img> 或者CSS背景图片),SMIL的交互效果也是没有的。

让SVG响应化

在嵌入SVG之后,你需要保证它是响应的。

根据你选择的嵌入技术,你需要应用一些特定的hack使得你的SVG是跨浏览器响应的,这是由于每个浏览器判定SVG的尺寸都不同,每个浏览器中SVG的实施方法也不同。因此,SVG的操作方法不尽相同,我们需要调整一些样式让SVG一直能跨浏览器响应。

我不会过多赘述浏览器矛盾,我只会简单介绍一下让SVG响应式所需的调整和hack。如果你想要了解浏览器矛盾和bug,可以看一下我在 Codrops上的文章

无论你选择什么技术,第一步要做的事情就是从 <svg> 元素中删除 height width 属性。

你需要保留 viewBox 属性,并把 preserveAspectRatio 属性设为 xMidYMid meet ,记住如果 preserveAspectRatio 的值已经默认为 xMidYMid meet 的话就不需要特意设置了。

当SVG作为CSS的背景图片嵌入时,不需要额外的调整或者hack,SVG会表现的和其他位图背景图片一模一样。

在所有浏览器中,如果SVG是通过 <img> 标签嵌入的话,SVG会自动拉伸到容器宽度(当然是在删除 <svg> 标签上的宽度值之后),然后它会按照预期伸缩,在除了IE之外的所有浏览器中自适应。IE会把SVG的高度设为150像素妨碍正确的伸缩。为了解决这个问题,你需要把 <img> 的宽度设为100%。

html
<img src="http://ued.ctrip.com/blog/mySVG.svg" alt="SVG Description." />
img {
  width: 100%;
}

这同样也适用于 <object> 标签嵌入,出于同样的原因考虑,你也需要设置 <object> 标签的宽度为100%:

css
object {
  width: 100%;
}

即使 <iframe> <object> 有很多相同之处,浏览器也会分别对待。所有浏览器会默认设置 CSS中替换元素的尺寸 为300*150像素。

保持SVG宽高比同时让iframe响应式的唯一方法,是使用由 A List Apart的Thierry Koblentz 首创的“padding hack”。padding hack的思路是利用元素padding和宽度的关系,来创建一个宽高比固定的元素。

当一个元素的padding值设为百分比,这个百分比会根据元素的宽度来计算,即使你设置的是元素的 padding-top padding-bottom

为了应用padding hack并使SVG响应化,SVG需要被装在一个容器中,然后你需要在容器和SVG(例如iframe)中添加样式。

html
    <!-- wrap svg in a container -->
    <div class="container">
        <iframe src="http://ued.ctrip.com/blog/my_SVG_file.svg">
        <!-- fallback here -->
        </iframe>
    </div>

.container {
  /* collapse the container's height */
  height: 0;        

  /* specify any width you want (a percentage value, basically) */     
  width: width-value;    

  /* apply padding using the following formula */
  /* this formula makes sure the aspect ratio of the container equals that of the SVG graphic */
  padding-top: (svg-height / svg-width) * width-value;
  position: relative;    /* create positioning context for SVG */
}

svg-height svg-width 变量分别是 <svg> 的高度和宽度值——就是我们之前删除的尺寸。 width-value 是你想要设置的任何SVG容器宽度。

最后,SVG自身(iframe)需要在容器中绝对定位:

css
iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

我们把iframe绝对定位的原因是合并容器的高度再加上padding会导致iframe超出容器边界。所以,“为了把它拉回来”,我们把它绝对定位。欲知详情,请看我 Codrops上的文章

最后,当我们把高度和宽度删除之后, <svg> 标签里的SVG会响应化,因为浏览器会假定一个100%的宽度,使得SVG按照这个宽度伸缩。然后,IE会像我们之前提到的 <img> 标签一样,有一个150像素的固定高度。不幸的是,把SVG的高度设为100%对这个bug无用。

为了让SVG在IE中自适应,我们也需要添加padding hack。所以,我们在 <svg> 标签外套一个容器,在容器中添加padding hack,最后让 <svg> 绝对定位,这里唯一的不同是,我们不需要设定 <svg> 的宽高。

css
svg {
  position: absolute;
  top: 0;
  left: 0;
}

使用CSS媒体查询

SVG也会接受并相应CSS媒体查询。你可以使用媒体查询来告便SVG在不同viewport下的样式。

然后这里有个很重要的注意事项,SVG相应地viewport是SVG本身的viewport,不是页面的viewport!

这跟 元素查询 的概念很像。

当SVG插入 <img> <object> <iframe> 中时,它响应的是这些元素建立起来的viewport。也就是说,这些元素的尺寸会生成描绘SVG的viewport,也会生成CSS媒体查询条件应用的viewport。

下面这个例子展示了包含媒体查询的SVG,SVG指定为 <img> 标签:

html
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 194 186">
  <style>
    @media all and (max-width: 50em) {
      /* select SVG elements and style them */
    } 
    @media all and (max-width: 30em) {
      /* styles  */
    }
  </style>
  <!-- SVG elements here -->
</svg>

<img> max-width 50em 或者 30em 时,SVG会应用媒体查询中的样式。

html
<img src="http://ued.ctrip.com/blog/my-logo.svg" alt="Page Logo." />

如果你想了解更多SVG中的媒体查询,你可以看一下 Dev.Opera中Andreas Bovens的文章

最后的话

SVG是图片,就像图片有可访问性一样,SVG也有,你需要保证你的SVG具有可访问性。

我还是要再强调一遍: 让你的SVG具有可访问性 ,你有很多种方法实现,如果你想要一个全面的概览,我推荐 SitePoint上Leonie Watson的文章 ,她提出一些很好的方法,比如在 <svg> 中使用 <title> <desc> 标签、使用ARIA属性等。

除了可访问性,不要忘记优化你的SVG,为不支持的浏览器提供回退。我推荐 Todd Parker的演讲

最后,你可以在 caniuse 上查看不同SVG特性的支持情况。我希望你觉得我这篇文章对你有用的,感谢你的阅读。

作者:携程UED
携程旅行前端开发团队
原文地址:【译】用css定义svg的样式和动画, 感谢原作者分享。

发表评论