svg是一种使用XML来描述二维图形和绘图程序的语言。svg格式图片是一种矢量图片,英文原名为Scalable Vector Graphics,是万维网联盟的标准,并与诸如DOM,XSL之类的W3C标准是一个整体。它主要由以下几个特点:
- 可伸缩,在任何分辨率下都具有高质量,不变形
- 是纯XML文本,读取和修改更加容易
- 和png、GIF相比,可压缩性更强,尺寸更小
寻找适合的svg图片
我们可以在:
icomoon或者http://iconfont.cn/上面获取svg图片,直接下载svg格式的图片到本地。
在http://iconfont.cn/里获取的svg图片是以一份XML的文档形式储存的,下载的时候会让你选择图片的格式,大小和颜色,最后下载的图片用编辑器打开会发现svg里面已经有相匹配的属性,如下是一个完整的svg图片代码:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg style="width:20px;height:20px;" version="1.1" id="图形" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="30px" height="30px" viewBox="0 0 1261 1024" enable-background="new 0 0 1261 1024" xml:space="preserve">
<path class="svgpath" data-index="path_0" fill="#ea8010" d="M236.307692 393.846154l-236.307692 630.153846 1024 0 236.307692-630.153846L236.307692 393.846154zM1024 315.076923 1024 157.538462 512 157.538462l-157.538462-157.538462L0 0l0 1024 157.538462-708.923077L1024 315.076923zM1024 315.076923" />
</svg>
在这里面,已经下载好了一个svg图片文件,有上面可以看出,这个文件里已经写好了内联的样式属性,所以,如果我们想要使用css样式来改变其样式,就会显得
svg图片的单文件引入方式
以下这几种方式都是单文件引入图片,这样引入会增加http的请求数,并且都不能使用css样式改变其颜色。
直接使用img标签引入图片:
<li><img src="../DOM_20160118/img/iconfont-wenjian.svg">file3</li>
- 使用img引入的方式就像平常引入img图片一样,只是格式不同;
- 可以在css中设置其宽高,并不会受svg标签中内联样式的约束;
使用
<embed>
标签引入图片:<embed src="../DOM_20160118/img/iconfont-wenjian.svg" type="image/svg+xml" />
可调整宽高使用
<object>
标签引入图片:<object data="../DOM_20160118/img/iconfont-wenjian.svg" type="image/svg+xml"> </object>
可调整宽高使用
<iframe>
标签引入图片:<iframe src="../DOM_20160118/img/iconfont-wenjian.svg"></iframe>
使用iframe引入的话,引入的是一个框,设置宽高设置的都是框的宽高,不会改变图片用svg标签直接放在代码里面
- 首先,我们可以在css样式中设置其宽高,因为其有内联样式,所以,在设置之后加上
!important
就行了; - 其次,可以使用fill属性来设置其颜色;
- 但是,将图片代码放在HTML中,会毁坏HTML的基本架构
- 首先,我们可以在css样式中设置其宽高,因为其有内联样式,所以,在设置之后加上
- 以上的几种方法是基本的引入svg单文件的方法,我们将介绍一个
svg sprite
技术;就如雪碧图一样将图片放在,然后在页面中引用。
svg sprite
参考链接: 从iconmoon中自动生成svg sprite
以上讲述了如何生成svg sprite,但是在引入单个文件确定坐标时却不方便,上面生成的图片具有很强的规律,所以并不符合一般引入图片的要求。
svg
本文建议使用此方法
在svg中,我们可以使用<use>
标签来引用svg中的一部分,这样就可以合并单文件为雪碧图减少请求数并且很方便的引用其中的某个图片。
可以这样说,<svg>
标签中有多个<symbol>
标签,每个<symbol>
标签都表示一个svg图片。
具体的实现方法如下:
- 如本文第一部分所示,下载图片到本地
- 使用前端自动化构建工具grunt将所有的svg单图片合成具有
symbol
标签的sprite图片- 首先生成package.json文件;
- 使用npm下载
grunt
和grunt-svgstore
插件到本地,关于grunt-svgstore
,可参考:https://github.com/FWeinb/grunt-svgstore/ - 在gruntfile.js文件中配置如下:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
svgstore: {
options: {},
//必须加上default,否则生成不了目的文件
default : {
files: {
'./dest/dest.svg': ['./SVG/*.svg'],
},
},
},
});
grunt.loadNpmTasks('grunt-svgstore');
grunt.registerTask('default', ['svgstore']);
};
- 生成的svg sprite的特点:
- 首先生成的每个`<symbol>`标签都有对应的ID,默认为图片名,还可以在option中设置前缀
- 使用时可以用css样式定义宽高,填充颜色
- 可以使用file形式打开文件,也可以用一个服务器打开
在HTML中引入,具体的引入方式有两种如下
第一,将生成的svg标签放在HTML的body元素的最上面,然后最HTML文本中引入如下:
<svg> <use xlink:href="#bullhorn"></use> </svg>
- 第二种方式直接引用生成的svg sprite里面的内容:
<svg>
<use xlink:href="./dest/dest.svg#bullhorn"></use>
</svg>
但是这种方式打开文件的时候不能使用file文件形式打开,必须起一个服务器打开,这种方式的引入更加的规范,不会造成HTML文档的结构混乱,建议使用这种方式。
这两种方式的引入在设置颜色时,必须确保引入文件的svg中没有对其颜色进行设置,但是往往世事不如人愿,所以现在我的解决方法是将源文件中的fill属性删除,可以使用sublime的快捷选择方式Ctrl+D
,这样就可以正常填充属性了。
svg图片与当前并列元素颜色同步
当我们在使用图标和字体配合时,我们往往希望在hover上字体时,他们能够一起变色,svg提供了一种非常有用的方式:
fill=correntColor;
这样可以使的图片可以同相对应字体颜色同步变化。但是必须保证在引用的方式中svg的fill属性在css样式中时可用的。
参考文献
【1】http://www.runoob.com/svg/svg-inhtml.html
【2】未来必热:SVG Sprite技术介绍
【3】使用SVG中的Symbol元素制作Icon