一、出现原因
使用雪碧图前需要制作雪碧图、还得进行精准测量等工作,所以为什么要用呢???
其实应该搞清楚开发一款产品不是为了开发人员怎么方便就怎么做,最终是为了提升用户体验,也就是性能!!!
下面看一个不用雪碧图的栗子(以淘宝的侧导航为例):
不用雪碧图想要用这些小图标需添加12个img标签或者是添加12个不一样的背景图
<ul class="nav">
<li class="icon1">
<img src="img/1.png" />
<a href="#">充话费</a>
</li>
<li class="icon2">
<img src="img/2.png" />
<a href="#">旅行</a>
</li>
<li class="icon3">
<img src="img/3 .png" />
<a href="#">车险</a>
</li>
<li class="icon4">
<img src="img/4.png" />
<a href="#">游戏</a>
</li>
<li class="icon5">
<img src="img/5.png" />
<a href="#">彩票</a>
</li>
<li class="icon6">
<img src="img/6.png" />
<a href="#">电影</a>
</li>
<li class="icon7">
<img src="img/7.png" />
<a href="#">酒店</a>
</li>
<li class="icon8">
<img src="img/8.png" />
<a href="#">理财</a>
</li>
<li class="icon9">
<img src="img/9.png" />
<a href="#">找服务</a>
</li>
<li class="icon10">
<img src="img/10.png" />
<a href="#">演出</a>
</li>
<li class="icon11">
<img src="img/11.png" />
<a href="#">水电煤</a>
</li>
<li class="icon12">
<img src="img/12.png" />
<a href="#">火车票</a>
</li>
</ul>
这样设置样式之后也可以达到上面的效果,但是再去看看控制台
1、2、3、4...12张小小的图片就占用了12个请求,如果是一个大型的网站有很多这样的小图片每次这样去请求,响应就会变慢,出现闪白等性能问题。这时候就需要我们的小精灵雪碧图啦~~~
二、原理、优缺点、使用场景
原理:把若干个小图标合成一张大图,通过给元素的公共css设置background-image来请求这一张大图,使每个元素都以这张大图为背景,这样页面只会加载这一张合成图,然后每个元素通过设置background-position来显示所需要的显示的位置即可。
优点:
减少网页的http请求,并防止出现闪白;
减少图片的字节,解决了图片命名上的困扰,只需对一张合成图片上命名就可以,不需要对每一个小元素进行命名;
更换风格方便,只需要在一张或少张图片上修改图片的颜色或样式,整个网页的风格就可以改变。
缺点:
在宽屏,高分辨率的屏幕下的自适应页面,你的图片如果不够宽,很容易出现背景断裂;
在开发的时候,要通过photoshop或其他工具测量计算每一个背景单元的精确位置;
在维护的时候比较麻烦,如果页面背景有少许改动,一般就要改这张合并的图片。
使用场景:
静态图片,不随用户信息的变化而变化;
小图片,图片容量比较小;
加载数量比较大。
三、用gulp制作雪碧图
那么问题来了,雪碧图如何制作?下面以gulp工具为例
首先需要安装生成sprite插件:在当前项目文件夹下打开命令行
1、局部安装gulp:npm install gulp
2、新建gulpfile.js文件
3、初始化项目:npm init
4、安装sprite插件:npm install --save-dev gulp.spritesmith
成功后就在gulpfile.js文件里写我们需要的代码,如下:
var gulp=require("gulp");
var spritesmith=require('gulp.spritesmith');
gulp.task('default', function () {
return gulp.src('img/*.png')//需要合并的图片地址(使用*通配符表示将所有图片合并)
.pipe(spritesmith({
imgName: 'sprite.png',//保存合并后图片的地址
cssName: 'css/sprite.css',//保存合并后对应的css样式的地址
padding:5,//合并时两个图片的间距
algorithm: 'top-down',//雪碧图的排列样式
}))
.pipe(gulp.dest('dist/'));
});
说明下Algorithm参数有四个可选值:top-down、left-right、diagonal、alt-diagonal、binary-tree
5、在命令行执行gulp,会生成如下文件
sprite.png就是合成的大图:
sprite.css中是生成的css已经算好了background-position值
.icon-1 { background-image: url(../sprite.png); background-position: 0px -289px; width: 18px; height: 24px; } .icon-2 { background-image: url(../sprite.png); background-position: 0px -97px; width: 24px; height: 21px; } .icon-3 { background-image: url(../sprite.png); background-position: 0px -149px; width: 24px; height: 22px; } .icon-4 { background-image: url(../sprite.png); background-position: 0px -47px; width: 24px; height: 20px; } .icon-5 { background-image: url(../sprite.png); background-position: 0px -176px; width: 22px; height: 23px; } .icon-6 { background-image: url(../sprite.png); background-position: 0px -72px; width: 24px; height: 20px; } .icon-7 { background-image: url(../sprite.png); background-position: 0px -23px; width: 20px; height: 19px; } .icon-8 { background-image: url(../sprite.png); background-position: 0px 0px; width: 24px; height: 18px; } .icon-9 { background-image: url(../sprite.png); background-position: 0px -204px; width: 22px; height: 23px; } .icon-10 { background-image: url(../sprite.png); background-position: 0px -123px; width: 18px; height: 21px; } .icon-11 { background-image: url(../sprite.png); background-position: 0px -232px; width: 18px; height: 23px; } .icon-12 { background-image: url(../sprite.png); background-position: 0px -260px; width: 22px; height: 24px; }
是不是爽歪歪、不需要自己去计算 background-position,从上面也可以看到12个用的是同一个背景图片:url(../sprite.png)
6、下面看看具体HTML的样式设置
<ul class="nav">
<li class="icon-1">
<i></i>
<a href="#">充话费</a>
</li>
<li class="icon-2">
<i></i>
<a href="#">旅行</a>
</li>
<li class="icon-3">
<i></i>
<a href="#">车险</a>
</li>
<li class="icon-4">
<i></i>
<a href="#">游戏</a>
</li>
<li class="icon-5">
<i></i>
<a href="#">彩票</a>
</li>
<li class="icon-6">
<i></i>
<a href="#">电影</a>
</li>
<li class="icon-7">
<i></i>
<a href="#">酒店</a>
</li>
<li class="icon-8">
<i></i>
<a href="#">理财</a>
</li>
<li class="icon-9">
<i></i>
<a href="#">找服务</a>
</li>
<li class="icon-10">
<i></i>
<a href="#">演出</a>
</li>
<li class="icon-11">
<i></i>
<a href="#">水电煤</a>
</li>
<li class="icon-12">
<i></i>
<a href="#">火车票</a>
</li>
</ul>
CSS样式如下:
ul{
width: 244px;
border-top: 1px solid #ccc;
border-left:1px solid #ccc;
margin: 0;
padding: 0;
}
li{
width: 60px;
height: 60px;
list-style: none;
line-height: 30px;
text-align: center;
float: left;
padding-top: 6px;
border: 1px solid #ccc;
border-top: transparent;
border-left: transparent;
}
li i{
display: block;
width: 24px;
height: 23px;
margin: auto;
background-image: url(dist/sprite.png);/*所有i标签的背景共用一张合成图*/
}
li a{
text-decoration: none;
outline-color: none;
font-size: 12px;
color: #000;
}
/*再单独给每个元素设置background-position值*/
.icon-1 i{
background-position: 0px -289px;
}
.icon-2 i{
background-position: 0px -97px;
}
.icon-3 i{
background-position: 0px -149px;
}
.icon-4 i{
background-position: 0px -47px;
}
.icon-5 i{
background-position: 0px -176px;
}
.icon-6 i{
background-position: 0px -72px;
}
.icon-7 i{
background-position: 0px -23px;
}
.icon-8 i{
background-position: 0px 0px;
}
.icon-9 i{
background-position: 0px -204px;
}
.icon-10 i{
background-position: 0px -123px;
}
.icon-11 i{
background-position: 0px -232px;
}
.icon-12 i{
background-position: 0px -260px;
}
现在看效果:
再打开看看控制台:
啦啦啦~对比一下开始12次请求,这个是不是看着舒服多了,不仅仅减少了请求次数,图片也小了很多。
四、最后再简单说下其他制作sprite的方法
1、国外的在线合成工具:http://csssprites.com/
选择需要合并的文件----设置option选项(包括:元素的间距,排列方式,背景颜色,边框)-----点击generate按钮生成
优点:自动合成,可以设置属性。
缺点:文件必须一个个地去选择导入,不能够批量导入。
2、腾讯的雪碧图在线生成工具http://alloyteam.github.io/gopng/
3、SpriteMe:国外的在线工具,它能够帮你分析页面中有哪些地方可以进行雪碧图的优化,并且能够生成对应的雪碧图。http://spriteme.org/
4、Webpack安装插件:npm install --save-dev webpack-spritesmith