在前端日常開發中,小圖標是必不可少的,我們該如何高效的處理小圖標是每位前端人要考慮的,下面這篇文章通過圖文實操給大家詳細介紹了關於前端處理小圖標的那些解決方案,對大家有一定的參考學習價值,需要的朋友們下面來一起看看吧。
前言
在開始本文之前,我們先做一個選擇題:前端發展使用建構工具的目的為何?
A、因為現在流行node.js,都在使用建置工具
B、讓前端開發變得高大上,和後端一樣編譯才能運作
C 、讓自動化工具取代重複的手動操作,例如合併程式碼,刷新瀏覽器預覽效果等。 選擇A、B請直接關閉此文,選擇C請繼續閱讀。 其實使用工具的目的就一個:自動化一些重複操作,提升工作效率。 ok,明確了這一點之後再來探究有哪些方式,可以把一堆小圖示合併成一個圖片檔案並產生對應的樣式。
依照產生檔案與使用方式來看,可以大致分成3類處理方式:#png sprite##
合成雪碧圖是歷史最悠久最成熟的解決方案,把不同的png小圖示拼接成一張png圖片。
有的公司甚至讓UI設計師合併小圖示(UI設計師變成了自動化工具,囧~),這樣做減少前端工作量的同時也帶來一些問題。
自動化工具
#當我們擁有了自動化工具的時候,部分問題就可以對整個流程進行最佳化了。
設定檔#以 npm 的 gulp.spritesmith 模組為例實作整個流程。
這是gulpfile.js 中設定的任務:
var gulp = require('gulp'); var $ = require('gulp-load-plugins')(); gulp.task('png', function () { gulp.src('./src/*.png') .pipe($.spritesmith({ imgName: 'icon.png', //参数,生成图片文件名 cssName: 'icon.css', //参数,生成的样式文件名 cssTemplate: './src/png_template.hbs' //参数,样式文件模板的路径,默认使用的是handlerbars模板 })) .pipe(gulp.dest('dist/png')); });
#
// 主要增加了一个通用样式,给图标赋予内联块级样式 .icon { display: inline-block; } {{#sprites}} .icon-{{name}} { background-image: url({{{escaped_image}}}); background-position: {{px.offset_x}} {{px.offset_y}}; width: {{px.width}}; height: {{px.height}}; } {{/sprites}}
配置完成之後,在來源資料夾中放入兩個question.png、hook.png 兩個小圖示進行調試。
gulp 處理後產生了兩個檔案:icon.css、icon.png。 開啟icon.css,可以看到根據圖示名稱產生了兩個樣式類別:
.icon { display: inline-block; } .icon-hook { background-image: url(icon.png); background-position: -40px 0px; width: 16px; height: 16px; } .icon-question { background-image: url(icon.png); background-position: 0px 0px; width: 40px; height: 40px; }
// 引用生成的css文件 <link rel="stylesheet" href="./png/icon.css" charset="utf-8"> ... //直接给标签添加样式类 <i class="icon icon-hook"></i> <i class="icon icon-question"></i>
問題感謝科技的進步和人民生活水準的提高,這種高效率的方式馬上碰到一個「天敵」:高dpr的視網膜螢幕。
用響應式判斷dpr的話,前面所有的工作量都要倍增,同時還要載入多餘的樣式。而且隨著螢幕更新換代,dpr增多就要多做一張圖片和样式,想想都太磨人 -_-||
那麼是否有圖片可以自適應不同dpr的螢幕? css3的曙光為我們指引了新的方向。
font-face
#也稱為字體圖標,這種技術簡單來說就是把向量圖合併產生字體文件,然後在css中引用對應的字體編碼即可渲染成圖片。因為字體是適應各種螢幕的,所以字體圖示也繼承了這個優點。
目前有不少製作字體圖示的網站,比較火的有icomoon、阿里巴巴圖示庫等。
基本操作都是在线上编辑图标,然后下载一个压缩包,包含字体文件和样式。首先的问题是不同图标大小需要手动调整 font-size 属性;其次就是手工操作太频繁:上传 - 编辑 - 下载;最后就是依赖网络环境,没网络就没法编辑图标。既然如此,我们尝试使用自动化工具离线生成文件。
自动化工具
依然使用的是github上star数比较多的模块 gulp-iconfont ,但是要同时生成css还需另一个模块 gulp-iconfont-css。
配置文件
配置 gulpfile.js
var gulp = require('gulp'); var $ = require('gulp-load-plugins')(); gulp.task('iconfont', function () { // 先配置样式,再配置字体文件 return gulp.src(['src/*.svg']) .pipe($.iconfontCss({ fontName: 'iconfont', //字体名 path: './src/font_template.css', //模板文件路径 cssClass: 'iconfont' //样式类名 })) .pipe($.iconfont({ fontName: 'iconfont', //字体名 formats: ['ttf', 'eot', 'woff', 'woff2', 'svg'] //输出的字体文件格式 })) .pipe(gulp.dest('dist/font')); });
此处省略模板文件~
开发流程
配置完成之后,在源文件夹中放入两个 question.svg、hook.svg 两个小图标进行调试。
gulp 处理后生成了6个文件: _icon.css、iconfont.eot、iconfont.svg、iconfont.ttf、iconfont.woff、iconfont.woff2。 打开 _icon.css,可以看到根据图标名生成了两个样式类:
@font-face { font-family: "iconfont"; src: url('./iconfont.eot'); src: url('./iconfont.eot?#iefix') format('eot'), url('./iconfont.woff2') format('woff2'), url('./iconfont.woff') format('woff'), url('./iconfont.ttf') format('truetype'), url('./iconfont.svg#iconfont') format('svg'); } .iconfont:before { font-family: "iconfont"; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-style: normal; font-variant: normal; font-weight: normal; /* speak: none; only necessary if not using the private unicode range (firstGlyph option) */ text-decoration: none; text-transform: none; } .iconfont-hook:before { content: "\E001"; } .iconfont-question:before { content: "\E002"; }
在代码中使用起来也很简单
// 引用生成的css文件 <link rel="stylesheet" href="./font/_icons.css" charset="utf-8"> ... //直接给标签添加样式类 <i class="iconfont iconfont-hook"></i> <i class="iconfont iconfont-question"></i>
预览效果见文末截图
使用问题
和之前的介绍的工具一样,可以使用模板,也可以生成scss、less、css多种格式文件。蛋疼的问题是:生成的所有的字体图标都会取最高的那个图标的高度。也就是说一些图标需要重新设置高度! 自动化操作瞬间降级为半自动化~而且生成的图片还带锯齿(不知道是不是配置问题),所以只能算是失败的方案。
svg sprite
正当愁眉不展之时,看到张鑫旭一篇文章《未来必热:SVG Sprite技术介绍》
(末尾的结束语将字体图标和svg sprite做了对比,有兴趣的朋友可以看一下)才让我感觉柳暗花明:原来还有更强大的svg sprite。将svg矢量图标整合成一个svg文件,使用的时候以 symbol 或 use 等标签的形式展现。
手动操作
考虑这个方案之时就没打算用手动化,因为如果需要手动操作还不如使用字体图标,所以直接考虑自动化工具。
自动化工具
使用的是github上star数仅次于gulp-svgstrore的模块 gulp-svg-sprite 。支持scss、less、css文件格式输出。
配置文件
var gulp = require('gulp'); var $ = require('gulp-load-plugins')(); gulp.task('svg', function () { return gulp.src('./src/*.svg') .pipe($.svgSprite({ mode: { symbol: { prefix: `.svg-`, dimensions: '%s', sprite: '../icon.svg', symbol: true, render: { css: { dest: '../icon.css' } } } } })) .pipe(gulp.dest('dist/svg')); });
开发流程
整个流程同上,配置完成之后,在源文件夹中放入两个 question.svg、hook.svg 两个小图标进行调试。
gulp 处理后生成了2个文件: icon.svg、icon.css。 打开 icon.css,可以看到根据图标名生成了两个样式类:
.svg-hook { width: 16px; height: 16px; } .svg-question { width: 40px; height: 40px; }
非常简洁有么有!!!
使用起来稍稍复杂一点:
//引用样式文件 <link rel="stylesheet" href="./svg/icon.css" charset="utf-8"> ... <svg class="svg-hook"> <use xlink:href="./svg/icon.svg#hook"></use> </svg> <svg class="svg-question"> <use xlink:href="./svg/icon.svg#question"></use> </svg>
预览效果见文末截图
相比字体图标:
据说SVG图标跟字体图标相比,还支持渐变,甚至彩色图标。
改变大小直接调整width和height属性即可,而不是调整font-size那种“曲线救国”的方式。
填充颜色也很简单,设置fill属性的值即可(前提是svg中不能使用fill,如果svg自带fill属性,设置失效)。
使用问题
所有的IE浏览器(包括IE11)还不支持获得外链SVG文件某个元件。但是也很好解决,使用第三方js即可——svg4everybody。
总结
以上是前端處理小圖示的技巧分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!