未来必热:SVG Sprite技术介绍

一、Sprite技术

这里所说的Sprite技术,没错,类似于CSS中的Sprite技术。图标图形整合在一起,实际呈现的时候准确显示特定图标。

另,本文图片甚多,爪机党继续浏览需慎重。

二、SVG Sprite与symbol元素

目前,SVG Sprite最佳实践是使用symbol元素。symbol元素是什么呢?单纯翻译的话,是“符号”的意思。然,这个释义并不符合这里的场景。不知大家有没有用过Flash,symbol实际上就类似于Flash中的“影片剪辑”、或者“元件”。

因此,我个人觉得,symbol应该解释为“元件”最为恰当!

那,symbol和SVG Sprite又有什么关系呢?

我们可以把SVG元素看成一个舞台,而symbol则是舞台上一个一个组装好的元件,这这些一个一个的元件就是我们即将使用的一个一个SVG图标。

于是,对于一个集合了三个SVG图标的SVG元素的代码结构会是这样:

<svg>
    <symbol>
        <!-- 第1个图标路径形状之类代码 -->
    </symbol>
    <symbol>
        <!-- 第2个图标路径形状之类代码 -->
    </symbol>
    <symbol>
        <!-- 第3个图标路径形状之类代码 -->
    </symbol>
</svg>

每一个symbol就是一个图标元件,但是,只有上面的代码,是无法呈现类似下面的效果的:
SVG Sprite的效果图

为何?

因为,舞台上只是放置了图标,如果你不使用(use),是看不见的。就好比你女朋友买了几箱的衣服放家里,如果不穿出去,谁知道她这么土豪呢?

因此,还差一个“使用”,也就是SVG中的<use>元素。

三、SVG中的use元素

use元素是SVG中非常强大,非常重要的一个元素,尤其在Web开发中,为何?

两点:

  1. 可重复调用;
  2. 跨SVG调用;

1. 可重复调用
你好不容易,用了几十个坐标值,好不容易绘制了一个图形,如果你想再弄一个同样造型,但位置不同的图形出来,你会怎么办?——再复制一遍代码?别说笑了,(如果真那样)SVG文件的尺寸赶得上二师兄的腰围了。

使用<use>元素就可以,看下面的板栗:

<svg>
  <defs>
    <g id="shape">
        <rect x="0" y="0" width="50" height="50" />
        <circle cx="0" cy="0" r="50" />
    </g>
  </defs>

  <use xlink:href="#shape" x="50" y="50" />
  <use xlink:href="#shape" x="200" y="50" />
</svg>

结果是(IE9+浏览器可见):

首先,注意到没有,use元素是通过xlink:href属性,寻找要使用的元素的。#shape对应的就是idshape的元素。use元素可以有自己的坐标,以及支持transform变换,甚至可以use其他use元素。

这里,两个use元素使用的是同一个g元素(组合),从而实现了图形的重复调用功能。

2. 跨SVG调用
SVG中的use元素可以调用其他SVG文件的元素,只要在一个文档中。

紧接着上面的板栗:

<svg width="500" height="110"><use xlink:href="#shape" x="50" y="50" /></svg>

结果仍是那个图形:

而这个跨SVG调用就是“SVG Sprite技术”的核心所在。

试想下,我们只要在页面某处载入一个充满Sprite(symbol)的SVG文件(或直接include SVG代码),于是,在页面的任何角落,只要想使用这个图标,只要简单这一点代码就可以了:

<svg class="size"><use xlink:href="#target" /></svg>

图标尺寸CSS控制,里面只有一个仅有xlink:href属性的use元素,Done! 完成!

也即是说,在HTML层面,图标使用的代码成本,跟传统的CSS Sprite或者流行的font-face几乎无异,代码简洁,而且很好维护。所有的SVG图标都在一个SVG源上。retina良好,尺寸可任意拉伸,且颜色可控,真乃Web图标的未来之星。

吹的嘴巴都干了,上个简单的demo给大家瞅瞅, 我先去给水排水~~

您可以狠狠地点击这里:SVG Sprite使用示意demo

代码如下截图:
SVG Sprite使用示意

效果为:
SVG使用的图标效果

总结下就是:symbol + use => SVG Sprite

诸位会不会觉得本文的内容快要结束了呢?

嘻嘻嘻嘻,顶多才1/3,下面的才是重点,打起精神,走起~~

四、SVG Sprite实际应用的阻碍

两大问题:

  1. SVG图标从何而来?
  2. SVG图标如何变成symbol并整合在一起?

1个问题,SVG图标从何而来?
“远在天边近在眼前”,CSS3 font-face的逐渐升温,让很多font-face工具诞生了。例如以前我介绍过的国外的icomoon.io,或者国内阿里系的iconfont.cn, 或者bootsrap 3粉们的font-awesome

这些图标实际上都是使用SVG作为媒介的,所以,根本就不要担心“SVG图标从何而来”,这图标多的就像牛魔王身上的虱子——一抖一大把啊!

OK,如何获得呢?直接下载。拿iconfont.cn示意,点击某一图标的下载按钮:
点击下载图标

点击下载SVG:
点击下载SVG按钮

于是,我们就得到了SVG图标啦!如果你还需要其他图标,也按照这个步骤一个一个下载下来,很简单吧~ 然后把它们放在一个文件夹中,以备后用。

下面最关键的是第2个问题,如何合并这些SVG到一个SVG上?同时满足使用的是symbol标签,并可以使用裸露的use元素(除了xlink:href没有其他属性)调用呢?

很长很funny, 要专门独立两段,

五、关于合并:偏开发的前端看这里

这里的方法适用于偏开发的前端,一些对指令无感的妹子们,可以看下面偏设计的方法。

Github上,有个名为svgstoregrunt插件,地址戳这里。如果您还不了解grunt, 可以看看这两篇我觉得不错的文章:“使用GruntJS构建Web程序 (1)”和“使用GruntJS构建Web程序 (2)”.

grunt改装的装好后,执行下面的指令,

npm install grunt-svgstore --save-dev

安装grunt-svgstore

烧个香保佑安装成功,然后你就会看到在node_modules文件夹中一个名为grunt-svgstore的子文件夹(如下):
grunt-svgstore文件夹

这个名为grunt-svgstore的文件夹中有个名为Gruntfile.js的文件,据我个人理解,这个JS是所有grunt插件要使用的配置文件。

我在里面做了一件事情,加了这么一行代码:
加了一行代码示意

为什么要加这么行代码呢?因为grunt-svgstore项目README.md让加的,所以我就加了

你会看到

svgstore: {

}

中有一大堆的配置什么的,这些都是用来独立测试各个API的(options对象中各个键就是API名称),让你知道此插件各个API都是干嘛用的,具体释义参见该Github项目。忍不住提一下,如果你希望SVG图标颜色可以在CSS中通过fill控制,cleanup设置为true.

OK, 准备工作完毕,下面来实践下。我把从iconfont.cn上下载下来的3个SVG都放在了一个名为mytest的文件夹下,我希望这个文件夹下的SVG都整合在一起,并可以方便调用,怎么办?

svgstore: {}内部搞个自定义的配置,见下图:
自定义的配置

意思是:mytest文件夹下的所有SVG合并成一个名为mytest.svg的大SVG文件,并放在tmp文件夹下。

我们cdgrunt-svgstore目录,然后在命令行工具中输入:

grunt

然后走起,再烧第2根香,保佑一切正常……
mytest走起~

然后,就可以在tmp文件夹下看到我们的小结晶——mytest.svg,以及如何使用示意的HTML demo页面。
SVG合并的文件,以及对应的demo~

此demo页面源代码如下:

<svg xmlns="http://www.w3.org/2000/svg" style="width:0;height:0;visibility:hidden;"><symbol viewBox="0 0 1024 1024" id="iconfont-baobei"><title>iconfont-baobei</title><path fill="#272636" d="M...z" transform="translate(0, 800) scale(1, -1)"/></symbol><symbol viewBox="0 0 1024 1024" id="iconfont-bianji"><title>iconfont-bianji</title><path fill="#272636" d="M...z" transform="translate(0, 800) scale(1, -1)"/></symbol><symbol viewBox="0 0 1024 1024" id="iconfont-shangchuan"><title>iconfont-shangchuan</title><path fill="#272636" d="M...z" transform="translate(0, 800) scale(1, -1)"/></symbol></svg>

<svg>
    <use xlink:href="#iconfont-baobei"></use>
</svg>
<svg>
    <use xlink:href="#iconfont-bianji"></use>
</svg>
<svg>
    <use xlink:href="#iconfont-shangchuan"></use>
</svg>

效果如下截图:
第一次成型的SVG效果图

Oh, no! 怎么有残缺,不完美,感觉不会再爱了!

淡定,小问题,貌似是这些SVG制作的时候,本身有些问题(为了font-face做的调整?),我们在illustrator中打开这些SVG, 一下子就可以看出症结所在,例如,细细的铅笔图标:
铅笔的两个角在舞台之外了

铅笔的两个角在白色的舞台之外了,正好跟上面截图少掉的两个角一致。要修复,超easy, 等比例缩放到白色舞台内就OK了,ctrl+S保存,然后重新执行下grunt命令就好了。

然后,浏览器刷新下刚刚的demo页面,当当当当,撒花撒花~~

溢出调整后的SVG效果

以上~

六、关于合并:偏设计的前端看这里

注意:这里的方法,就算是CSS完全不懂的设计师也可以轻松上手!

对于一些妹子,只会写些页面,对于开发、编程的感觉比减肥还难,显然,上面的偏开发需编译的工具插件对她们就很吃力。不急不急,这里有面向设计师的方法。

你需要一个犀利的软件,矢量之王,illustrator!

一步一步跟我来:

  1. 打开软件,新建一个文件,然后另存为SVG格式;
  2. 从标尺中拉出一些参考线,搞些正方形格子,我自己用的尺寸是160*160, 矢量无尺寸,你随意;
  3. 把下载的SVG图形拖到这些格子中,缩放到合适大小。我是铺满的,这样由于对比明显,各个图标尺寸就都是一致的,CSS控制方便;
    illustrator参考线与图形缩放
  4. 这一步很关键。打开Symbols面板,在Window菜单栏中,或Shift+Ctrl+F11启用。然后,拖动格子中的SVG图形到这个面板中,就会触发新建“元件”的行为,会打开类似下面的面板:
    illustrator中新建元件的面板

    其中,name就是SVG中对应的symbol元素的id,因此,最好使用英文,最好易识别。下面的type你随意,这个只要在SVG导入到Flash中使用时候才有用的,这里,我们不和Flash打交道。然后,OK, 这个图标就“元件”化了,按照同样的步骤,让3个图标都变成元件(以后可重复使用),Symbols面板会类似下面这样:
    Symbols面板截图

  5. Ctrl+S保存,合并好的SVG即出炉。我们直接在浏览器中打开此SVG,效果不错哦~
    SVG Sprite的效果图

是不是就这么结束了,太天真了。人生不如意事十之八九。我们瞅一瞅SVG的源代码,会发现,use元素居然跟小龙女一样,不干净纯洁啦——上面一大推乱七八糟的属性!
use元素上大把乱七八糟属性

难道我们要在网页中使用如此臃肿的use元素吗?

我以小新的明义告诉你,绝对不会!

小新的名义

因为我昨晚在家折腾出了个工具,可以将illustrator生成SVG转换成web可用SVG Sprite.

您可以狠狠地点击这里:illustrator生成SVG转换成web可用SVG Sprite工具demo

上工具完整地址是:http://www.zhangxinxu.com/sp/svg.html 很好记忆,我站点域名+sp+svg.html, spspecial的缩写,专门放工具用的。

使用很简单:

  1. 把illustrator生成SVG所有代码拷贝到第一个框框里;
  2. 点击“转换萌萌哒”按钮,适用于SVG Sprite技术的新代码就出来了(左下的框框);同时,右侧显示了如何使用该SVG Sprite在web中真实实践;
  3. 左下角还有个红色的“导出该SVG”,就是字面意思,可以自定义名称,也可使用随机名称,为空即可;

一开始的SVG Sprite使用示意demo就是使用这个工具生成的哦~ 见下缩略图:
illustrator生成SVG转换工具使用截图

注意:此工具值适用于illustrator生成的SVG, 水平有限,其他SVG转换十有八九会跛掉。没怎么测试,如果发现此工具转换出了问题,欢迎提醒,定会及时修复。另外,生成的SVG文件会不定期清理,请勿外链。

我想想,还有没有什么问题……哦,为什么说此方法与CSS Sprite还要简单。

因为,CSS Sprite还需要在CSS中使用background-position一个一个地定位,哦,天哪~ 如果没有工具的话,就纯粹搬砖的苦力活啊~

但是,这里的SVG Sprite的定位,你只要在illustrator中把位置放好,illustrator这个软件就自动帮你定位好了。你只要在我的工具中转换下,生成下,然后在需要使用的地方使用:

<svg><use xlink:href="#target" /></svg>

就好了,用到CSS了吗?几乎没有,除了对SVG做尺寸限制以及改变图标的颜色。OK,这点程度的东西,小白设计师也可以轻松上手。

从这一点来看,SVG又一次成为了明日之星!设计师只要在illustrator中做好图就可以了,完全没有从前那种帮重构切图的苦逼经历了,是不是要啤酒炸鸡庆祝下!

补充于2014年7月14日
IcoMoon目前可以直接转换成SVG Sprite.

  1. 进入 http://icomoon.io/app/
  2. 点击”import icons”按钮:
    添加图标按钮
  3. 选择需要的图标:
    选择需要的图标
  4. 点击页面下面固定的SVG按钮:
    SVG按钮
  5. 点击打开的弹框的download按钮即可:
    下载SVG Sprite弹框以及按钮
  6. 下载的源文件中,有两个文件夹,其中sprites文件夹中,有合并好的SVG, png图标以及对应的demo, 这个绝不会迷路的,就不截图展示了。

嘛,就此看来,这里才是老少皆宜,SVG Sprites整合最容易的地方。不过:

  1. 元素还是使用的g整合,svgstore以前也是,后来改成了symbol, 这里也可能在一段时日后也会修改,但并不确定;
  2. 名为sprites.html的demo页面的SVG还使用了viewbox做限制,我测试了,删掉似乎也没问题;

补充于2014年12月21日
注意注意:SVG Sprite技术是支持外链SVG文件的,例如:

<svg viewBox="0 0 100 100"> <use xlink:href="defs.svg#icon-1"></use> </svg>

所以,很多不喜欢内联SVG的小伙伴大可放心使用该技术。但是,美中不足的是,目前,所有的IE浏览器(包括IE11)还不支持获得外链SVG文件某个元件。Chrome/FireFox/Safari/Opera等浏览器都是OK的。

补充于2015年3月18日
SVG Sprite技术是支持直接Ajax请求SVG文件字符串的。因此,对于不支持外链的IE9+浏览器,可以直接:

var ajax = new XMLHttpRequest();
ajax.open("GET", "../201407/mytest.svg", true);
ajax.onload = function(e) {
    document.body.insertAdjacentHTML("afterBegin", '<div style="display:none;">' + ajax.responseText + '</div>');
}
ajax.send();

您可以狠狠地点击这里:Ajax请求SVG文件实现Sprites效果Demo

例如,IE9浏览器下:
IE9浏览器下SVG Ajax请求示意

因此,大家大可不必担心SVG资源管理之类的问题。IE9等浏览器,一次Ajax成功后,可以直接本地存储,想想就很棒!

补充于2016年10月27日
部分华为Android手机,这种后置的ajax请求SVG写入方式无法呈现小图标,如果在页面头部一开始就有SVG文件代码资源,则没有此问题,图标不会显示不出来。

要修复此方法,可以把SVG资源作为一个JS资源载入,例如,命名一个名叫sprite.js,里面代码大致如下:

var SVG = '<svg xmlns="http://www.w3.org/2000/svg"><symbol id="icon-arrow-l" viewBox="0 0 8 16"><path d="M.146 7.646a.5.5 0 0 0 0 .708l7 7a.5.5 0 0 0 .708-.708l-7-7v.708l7-7a.5.5 0 0 0-.708-.708l-7 7z"/></symbol><symbol id="icon-arrow-r" viewBox="0 0 7 12"><path d="M6.146 6.354v-.708l-5.5 5.5a.5.5 0 0 0 .708.708l5.5-5.5a.5.5 0 0 0 0-.708l-5.5-5.5a.5.5 0 1 0-.708.708l5.5 5.5z"/></symbol><symbol ....</symbol></svg>';
document.body.insertAdjacentHTML("afterBegin", '');

然后在页面body标签的下面,直接:

<script src="sprite.js"></script>

类似下图:
sprite.js放置在body标签的下面

七、唯一的制约——兼容性

SVG图标必定是未来的趋势。为何现在国内依然不温不火,不对,应该是还没有开始有温度。我觉得除了技术学习滞后性,浏览器兼容性是最关键的制约,毕竟IE8目前依然是大头(33.23%, 刚在百度流量研究院看到的数据)。

如何破?按照我的心情,鸟它个毛线,我就手机上用用,不也挺好。静下来想想,不能意气用事,提一下IE7/IE8浏览器的处理方法吧~

有些标签,浏览器识别,会忽略里面一些东西。例如SVG的desc元素,里面的内容一向不显示的。于是,对于IE7/IE8, 我们可以把对应图标的png图片放在其中,然后IE9+等支持SVG的浏览器就会忽略之,而IE7/IE8这些不识泰山的元素就会显示图片。拿礼物这个SVG举例:

<svg class="webicon">
    <desc><img src="iconfont-baobei.png" width="16" height="16"></desc>
    <use xlink:href="#liwu"/>
</svg>兑换礼物

于是,在IE8下,就会是这样:
IE8浏览器下效果

其他靠谱浏览器依然是这样:
SVG使用的图标效果

于是,完美兼容了。只是活脱脱多了个标签,略败兴。当然,你也可以针对IE7/IE8使用CSS Sprite技术,原理类似,只是img标签换成其他i之类标签显示背景图,至少HTML这块会干净很多。

八、结束语

今年4月份的时候刚介绍过“CSS3图标图形生成技术”,如果说“font-face图标生成技术”是热门的话,那“CSS3图标生成技术”则属于偏门,受设计制约很大,而本文介绍的“SVG Sprite图标生成”则代表了未来。

font-face在部分win系统下,字体较小的时候,锯齿问题很讨厌,苛刻的设计师无法忍受,甚至出现了响应式font-face这样的名堂,但是,据我观察,纯正的SVG图标是没有这个问题的,而且,SVG图标具备font-face几乎所有的优点,尺寸CSS可随意定制,颜色CSS可随意定制;且没有font-face异步加载延时渲染问题;同时没有某些浏览器下font-face跨域问题;更关键的是,SVG图标支持渐变,甚至彩色图标的。而font-face实现彩色图标,要一个一个拼起来,你以为贴马赛克啊!而且,SVG中每个path元素等可以独立控制,帅气的图标变换动画等的就是你来实现(add on 2014/7/18 这个页面N多SVG图标动画)!

因此,各方面看,SVG完胜font-face,

目前唯一的问题就是兼容成本(当然,业界还是有很多成熟的优雅降级技术,可参见我之前的文章“一些SVG向下兼容优雅降级技术”)。但是,随着浏览器的发展,SVG一定会迎来自己Web新舞台!

感谢阅读,欢迎交流,踊跃纠错,多多赞助!

(本篇完)

分享到:

标签: , , , , , , , , ,

赞助商推荐(我也要赞助)

想学到点真东西? ×
如果你有1~3年前端开发经验,不妨 ×
想找个师兄入门前端?不妨 ×
想快速入门前端? ×


发表评论(目前51 条评论)

  1. 365189883说道:

    大神 工具崩了

  2. 隔壁住着梦想家说道:

    SVG Sprite相对于font-face在图标属性的处理上要优秀许多,但SVG Sprite兼容性及写法
    “”,
    要比”“font-face的方法还是麻烦一点.

  3. 小花鹿说道:

    “grunt改装的装好后”,错别字

  4. 关于SVG Sprite说道:

    SVG Sprite外链SVG文件时显示不出来是怎么回事,内联的时候是可以的

  5. dg_zhm说道:

    您好,我最近在做一个svg的需求,请问使用embed标签引入svg后如何实现对svg的拖动和缩放呢?

  6. undefined说道:

    生成的svg文件颜色有问题

  7. tabris17说道:

    如果css能够支持SVG就好了,这样子还是会污染HTML代码

  8. leungwensen说道:

    马上开始使用SVG吧! http://leungwensen.github.io/svg-icon/ 支持几乎所有流行的iconfonts,可以直接按需选择下载为SVG sprite文件

  9. 阿牛说道:

    用了gulp-svgstore合并出来的svg文件用浏览器打开是空白了 有人碰到过这个问题吗?

    • null说道:

      你不能直接打开svg文件。。。。应该打开demo那个html,svg文件svg icon元素包含在标签里面是不会被渲染出来的,必须要use它才行

  10. 刘朋涛说道:

    刚接触svg,想做个流程设计器 求指导

  11. abaddonpoet说道:

    未来大热这flag竖的。。。。
    svg好久前就在等待,然而兼容性一直没解决。。。去git上找了下相关svg接html5或者canvas的项目,po主已经明确说弃坑多年。。而且设想1下,最适合使用的几个地方,比如可能是边缘无规则的地图图形,然而数据量肯定会很庞大不如2种尺寸清晰度的图片根据环境切换。还有字体、icon,已经有解决方案~~自定义的小字库font-face。。。。虽然都感觉是未来的方向,然而感觉遥遥无期。。。。我猜估计要等vr来推动手机pc的兼容性改进了

  12. imfiny说道:

    拜读,长知识

  13. kinder说道:

    SVG Sprite技术是支持外链SVG文件。
    这个点我用火狐,谷歌都试了下,发现并不支持。
    直接把SVG置入HTML中倒是支持,大神能解答下吗?

  14. Ai导出的图像旋转问题说道:

    不知道你有没有发现,ai导出的svg如果删除这一句transform=”matrix(1 0 0 -1 0 0)”的话,图像就会倒置,难道ai导出的图像本身就是倒置的,渲染的时候强制旋转吗

  15. 李家良说道:

    拜读了大神的文章,测试了一下,主要问题还是 svg symbols的兼容性,测试过安卓版UC不兼容,QQ没问题,ios其他浏览器暂无发现问题

  16. 用Ai导出的svg文件,很多冗余的信息说道:

    用你的工具无法压缩成功

  17. AC说道:

    SVG挺好,不过不兼容IE8,font-awesome 倒是可以哒

  18. King Deng说道:

    我最近在用svg写一个小程序,遇到了一个问题,不知博主是否知道怎么解决。问题如下:
    我想在页面载入之后,通过点击一个按钮,动态添加一个,代码:
    var use = document.createElementNS(“http://www.w3.org/2000/svg”, “use”);
    $(use).attr(“xlink:href”, “#id”);
    这种方式虽然能在文档的DOM中插入一个use,但是就是在页面显示不出来,其他图形path、polygon等都可以用这种方式动态添加,但use不行,不知博主有什么解决办法没有?

  19. 羊哥很忙说道:

    关于合并,我在网上找到一个十分方便的工具
    http://editor.method.ac/
    在线编辑svg,用后感觉效果很好,你可以试一试哈。

  20. 酷我配乐说道:

    好象IcoMoon现在又不支持svg sprite了

  21. 任光辉说道:

    使用IcoMoon转换成的SVG Sprite.使用的时候大小不能自由改变。请教这是怎么回事?

  22. 甜甜甜说道:

    感谢lz分享~不过有一个小问题,如果做按钮,hover的时候改变图片(背景颜色和图标颜色反转)是不是需要替换整个的div?可以通过css直接实现吗?

  23. 飞露说道:

    我感觉 图标无非就是一些 三角形 矩形 梯形 圆形 等等拼合而成的 symbol 可以用这些基础元素 具体的图标 去拼接好了 这样是不是可以省一些流量哈哈

  24. 楼主好像忽略了iconfont网站的很多功能,其实iconfont.cn 提供了svg下载,也提供了多个图标组成的svg字体文件的下载,您只需点击图标,把图标放入购物车中,点击即可打包下载很多图标,如果您用微博账号登录iconfont平台后,您还可以使用iconfont提供的图标项目库的功能,这样的话您在项目图标库中可以编辑图标的大小等等功能;

    可以加我微博:http://weibo.com/iconfont

    细聊

    • 张 鑫旭说道:

      @iconfont.cn 跟字体文件一起打包的那个SVG我瞅过,不能直接在web中使用。IcoMoon则是有打包字体SVG下载, 同时提供了SVG Sprites打包下载。

  25. SJY说道:

    在Chrome中,当进行叶面缩放时有问题。
    博主可以测试下第一DEMO。

  26. Mask说道:

    我发现icomoon已经可以直接生成svg spirit了,把svg拖到icomoon,一切就自动搞定了。。。 我不会也是来砸场子的吧。。。呵呵
    不过我的worry也和AlphaTr 类似,svg怎样才能像css一样外部调用呢?如果每个html都需要放进去这么一堆东西,如果我要修改svg spirit会很不现实。如果用后端语言,貌似也不完美,有木有link那样的方法列~

  27. 陆离说道:

    其实也没那么麻烦了。

    用svgstore可以直接把指定文件夹下的svg文件合并成一个新的svg文件,并把各svg文件名作为各个symbol的id,直接把这个svg文件的内容粘贴到html里就可以直接use了。也不用ill再定位合并什么的。

    所以设计要做的就是找到图标,然后把svg图标命名好了扔到文件夹里就行啦。

    再优化的话可以用grunt自动把svg文件插入到HTML里,或者自动往HTML里类似于的标签里写,这样开发的时候也只需要写个就可以了。

    写么长串的HTML还是有点麻烦的。

  28. 依云说道:

    「symbol」在 Flash 里的翻译就是「元件」啦~

  29. niphor说道:

    如果引入2个svg,里面id相同的怎么办?
    必须放页面里面也是个问题,假如app用不到后台生成页面的,这个也略麻烦
    又或者图标在N个页面上都有,每个页面都得插入,消耗了多余的流量,如果图标分散在多个svg中,更是蛋疼了

    • 张 鑫旭说道:

      @niphor 1. id相同这个跟普通HTML的id相同是一个档次的低级失误;
      2. 由于SVG是正宗的字符串,可以使用localstorage存储在本地,也就是说,一次加载,万年使用,没有什么流量消耗的。配合一些自定义的更新规则,要比各种font字体文件好维护的多。

  30. 怡红公子说道:

    看完叻,又学习到啦,给赞的说。话说我感觉应该可以纯手工操作合并svg图吧,可能会略麻烦一下就是…
    另外,在线转换工具生成文件似乎用了后端?为什么不用Blob呢?这样就不用在服务器上存储了。

  31. AlphaTr说道:

    这里有两个问题:

    1. svg 貌似必须直接写在页面,通过 svg 文件引入是无效的,这样就让页面源码看起来不怎么好看了;

    2. svg 颜色是在 svg 里面定义的,所以在使用上还是感觉没有像 Web fonts 这样在文件外定义好用;

    • 张 鑫旭说道:

      @AlphaTr 1. 使用后台语言,可以直接include SVG文件的,文章的HTML源码示意截图可见(PHP引入)。开发的时候,不会有一堆源码干扰的;实际输出的一堆压缩的HTML源码,没人会关心的。
      2. SVG颜色是可以外部CSS定义的,文章已经多次提到。

      • AlphaTr说道:

        抱歉,我可能没有表达清楚;svg 最让我纠结的就是它的使用方式,文中提到的 Sprite 依托于 svg 直接输出到 html 文件,那样 css 也是可以定义的,但是如果通过前端的 svg 文件引入的话,这样就较难实现了,而我觉得在一些场合,外联的 svg 可能用处更大。