- Icon Sprites
- Gulp配置字体精灵任务
- 拼合字体精灵文件到样式文件中
- 使用字体
- Gulp执行一系列任务
Icon Sprites
我们的页面里使用了很多图标文件,每个图标文件都是一个svg文件。页面在加载的时候,如果图标文件有很多,会一个个加载,比较慢,因为切换下载不同的文件也有开销。
前端开发中经常使用一种叫做Sprites也就是精灵图的技术,就是把一堆小图片或者字体,打包成一个文件下载。如果是图片,就利用不同的定位和大小来显示不同的内容,这样一个文件就可以复用。
字体也可以用类似的方式,一次性加载很多字体,这就是Icon Sprites。
Gulp配置字体精灵任务
Gulp的所有动作都要通过任务来实现,在tasks
目录下创建sprites.js
。
编写任务之前,还需要装一个包来管理字体:
npm install gulp-svg-sprite --save-dev
安装完成之后,编写如下任务代码:
let gulp = require('gulp'),
svgSprite = require('gulp-svg-sprite');
let config = {
mode:{
css:{
}
}
};
gulp.task('createSprite', function () {
return gulp.src('./app/assets/images/icons/**/*.svg')
.pipe(svgSprite(config))
.pipe(gulp.dest("./app/temp/sprite/"))
;
});
这段代码将所有的svg文件通过管道,配置插件的模式为css,然后在指定目录生成了一个CSS文件,里边包含所有的SVG信息。
运行这个任务,然后可以看到生成了app/temp/sprite/css/svg/sprite.css-d675eadb.svg
这个文件,点开可以看到类似精灵图的样子。
要使用这个图,如果自己编写CSS代码,需要指定偏移坐标,比较麻烦。好在这个工具可以进一步配置,生成具体的CSS代码供引用。由于需要使用一个模板,在gulp
目录下创建templates
目录,在其中创建一个名称自定义的css文件作为css模板,比如sprites.css
。
这个模板采用胡子标签渲染,编写如下:
{{#shapes}}
.icon--{{base}} {
width:{{width.outer}}px;
height: {{height.outer}}px;
background-image: url('/temp/sprite/css/{{{sprite}}}');
background-position: {{position.relative.xy}};
}
{{/shapes}}
最外边表示遍历所有的svg对象,然后依次列出其名称对应的样式类,有外宽度,高度,背景图片的来源和相对位置。
注意,由于index.html文件所在的app目录是项目目录,这里需要引用拼合后的文件,而其文件名有自动生成的后缀,所以这里的background-image的路径要注意,最后使用三个花括号表示不转义\
,sprite变量表示拼合后的精灵字体文件。
还需要修改任务文件,配置使用这个模板进行渲染:
let config = {
mode:{
css:{
render:{
css:{
template:'./gulp/templates/sprites.css'
}
}
}
}
};
再次运行任务,可以看到生成的CSS文件:
.icon--clear-view-escapes {
width:142.4px;
height: 59.53px;
background-image: url('/temp/sprite/css/svg/sprite.css-d675eadb.svg');
background-position: 0 0;
}
.icon--comment {
width:64px;
height: 64px;
background-image: url('/temp/sprite/css/svg/sprite.css-d675eadb.svg');
background-position: 99.70443349753694% 0;
}
.icon--facebook {
width:21.23px;
height: 42.01px;
background-image: url('/temp/sprite/css/svg/sprite.css-d675eadb.svg');
background-position: 26.040607071652357% 45.795830448496034%;
}
......
剩下要做的就是在页面内按照样式来引用了
拼合字体精灵文件到样式文件中
我们直接把字体文件也生成到了最终文件目录也就是temp目录下,因此需要在页面内引入该CSS文件。
这里有两种思路,一是将该字体文件作为单独的文件引入,二是将该字体文件拼合到其他的CSS文件中。
第一种比较简单,不多说。
第二种我们可以在styles.css文件中直接导入生成后的文件,但是由于该文件位于目标目录下,直接导入会打破原来的环境。
这里可以创建一个任务,将生成的css文件复制到工程目录下的某处,同时修改名称,再导入然后进行处理:
需要先装一个插件,自动改名:
npm install gulp-rename --save-dev
然后在sprites.js
里新建一个任务:
gulp.task('copySpriteCSS', function () {
return gulp.src('./app/temp/sprite/css/*.css')
.pipe(rename('_sprite.css'))
.pipe(gulp.dest('./app/assets/styles/modules/'));
只要运行这个任务,就自动复制过去然后改名了,之后在styles.css
文件中导入,就完成了准备工作。
使用字体
拼合好之后,实际的CSS文件已经有了上述的类,现在就是要应用到原来以img形式存在的SVG图标元素上了。
以这段为例:
<h2 class="section-title">
<img class="section-title__icon" src="assets/images/icons/star.svg">Our <strong>Features</strong>
</h2>
之后就像原来的图标一样使用了。我这里遇到的问题是使用SPAN
标签无法正常显示SVG,不知道为什么。。。
Gulp执行一系列任务
var gulp = require('gulp'),
svgSprite = require('gulp-svg-sprite'),
rename = require('gulp-rename'),
del = require('del');
var config = {
mode: {
css: {
sprite: 'sprite.svg',
render: {
css: {
template: './gulp/templates/sprite.css'
}
}
}
}
};
gulp.task('beginClean', function() {
return del(['./app/temp/sprite', './app/assets/images/sprites']);
});
gulp.task('createSprite', ['beginClean'], function() {
return gulp.src('./app/assets/images/icons/**/*.svg')
.pipe(svgSprite(config))
.pipe(gulp.dest('./app/temp/sprite/'));
});
gulp.task('copySpriteGraphic', ['createSprite'], function() {
return gulp.src('./app/temp/sprite/css/**/*.svg')
.pipe(gulp.dest('./app/assets/images/sprites'));
});
gulp.task('copySpriteCSS', ['createSprite'], function() {
return gulp.src('./app/temp/sprite/css/*.css')
.pipe(rename('_sprite.css'))
.pipe(gulp.dest('./app/assets/styles/modules'));
});
gulp.task('endClean', ['copySpriteGraphic', 'copySpriteCSS'], function() {
return del('./app/temp/sprite');
});
gulp.task('icons', ['beginClean', 'createSprite', 'copySpriteGraphic', 'copySpriteCSS', 'endClean']);
最后编写的任务文件如下,包含了创建新文件,清理原来文件,复制等一系列过程。
Gulp可以使用第二个参数为一个数组,来传入需要依次执行的任务。
自此就完全搭建好了CSS方面的工作流。在搭建CSS工作流的时候一定要注意项目的目录结构。