SVGスプライトの使用方法

こんにちは、開発者!

PSDからレイアウトを植字する場合、アイコンは多くの場合SVG形式で挿入されます。 そうでない場合は、デザイナーに依頼します。 以前は、アイコンフォントを使用していましたが、最近、スプライトの利点を知り、 それらを試し 、開発プロセスに導入することにしました。 アイコンフォントは好きですが、いくつかの欠点があります(このトピックについてはCSSTricksを読んでください )。 実験は成功し、これが私がシステムを編成した方法です。



条件



スプライトから取得したいもの:

  1. アイコンのサイズ、色、動作(ホバー、フォーカスなど)を柔軟に制御
  2. 自動化、最小限の手作業
  3. 優れたページ読み込み速度のためのアイコンキャッシュ
  4. ページレイアウトへのアイコンの簡単な挿入(ヒスイを使用してHTMLをテンプレート化)




私のフォルダー構造:

├── gulpfile.js # gulpfile └──assets #    └── jade/ #  html └── sass/ #  └── js/ #  └── i/ # ,       └──dist #    
      
      







私のアセンブリがリポジトリでどのように機能するかについての詳細を読むことができます

スプライトを作成するには、gulpを使用します。つまり:





行こう!



プラグインをインストールします(これをグローバルに実行してからリンクします):

 npm install gulp-svg-sprites gulp-svgmin gulp-cheerio gulp-replace -g npm link gulp-svg-sprites gulp-svgmin gulp-cheerio gulp-replace
      
      





gulpfileでプラグインを宣言します:

 var svgSprite = require('gulp-svg-sprites'), svgmin = require('gulp-svgmin'), cheerio = require('gulp-cheerio'), replace = require('gulp-replace');
      
      







クックスプライト



最初のタスクは、 シンボルタグを使用してhtmlファイルを作成することです。

 gulp.task('svgSpriteBuild', function () { return gulp.src(assetsDir + 'i/icons/*.svg') // minify svg .pipe(svgmin({ js2svg: { pretty: true } })) // remove all fill and style declarations in out shapes .pipe(cheerio({ run: function ($) { $('[fill]').removeAttr('fill'); $('[style]').removeAttr('style'); }, parserOptions: { xmlMode: true } })) // cheerio plugin create unnecessary string '>', so replace it. .pipe(replace('>', '>')) // build svg sprite .pipe(svgSprite({ mode: "symbols", preview: false, selector: "icon-%f", svg: { symbols: 'symbol_sprite.html' } } )) .pipe(gulp.dest(assetsDir + 'i/')); });
      
      





ここで部分的に何が起こるか見てみましょう。

アイコンを取得して縮小する必要がある場所を示します。 変数assetDirは便宜上のものです。

 return gulp.src(assetsDir + 'i/icons/*.svg') // minify svg .pipe(svgmin({ js2svg: { pretty: true } }))
      
      





スタイルを削除し、CSSで指定されたスタイルを中断しないようにアイコンから属性を塗りつぶします。

 .pipe(cheerio({ run: function ($) { $('[fill]').removeAttr('fill'); $('[style]').removeAttr('style'); }, parserOptions: { xmlMode: true } }))
      
      





しかし、このプラグインに1つのバグがあることに気づきました-文字 '>'をエンコーディング '>'に変換する場合があります。

次のタスクでこの問題を解決します。

 .pipe(replace('>', '>'))
      
      





次に、結果のスプライトからスプライトを作成して、フォルダーに配置します。

 .pipe(svgSprite({ mode: "symbols", preview: false, selector: "icon-%f", svg: { symbols: 'symbol_sprite.html' } } )) .pipe(gulp.dest(assetsDir + 'i/'));
      
      





symbol_sprite.html-これはスプライトです。 内部には次のものが含まれます(簡単にするために、いくつかのアイコンがあります)。

 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="0" height="0" style="position:absolute"> <symbol id="icon-burger" viewBox="0 0 66 64"> <path fill-rule="evenodd" clip-rule="evenodd" d="M0 0h66v9H0V0zm0 27h66v9H0v-9zm0 27h66v9H0v-9z"/> </symbol> <symbol id="icon-check_round" viewBox="-0.501 -0.752 18 18"> <path d="M8.355 0C3.748 0 0 3.748 0 8.355s3.748 8.355 8.355 8.355 8.355-3.748 8.355-8.355S12.962 0 8.355 0zm0 15.363c-3.865 0-7.01-3.144-7.01-7.01 0-3.864 3.145-7.007 7.01-7.007s7.01 3.144 7.01 7.01-3.146 7.007-7.01 7.007z"/> <path d="M11.018 5.69l-3.9 3.9L5.69 8.165c-.262-.263-.688-.263-.95 0-.264.263-.264.69 0 .952l1.9 1.903c.132.13.304.196.476.196s.344-.066.476-.197l4.376-4.378c.263-.263.263-.69 0-.952s-.69-.262-.952 0z"/> </symbol> </svg>
      
      





スタイルのピンチ



次に、スプ​​ライト(この場合は.scssファイル)のスタイルを作成する必要があります。 gulp-svg-spritesプラグインでは、このファイルを指定できますが、面倒な点があります。この設定ではできません。

 mode: "symbols"
      
      





scssを作成するために別のタスクを作成することにしました。 別の解決策を見つけたら、コメントを書いてください。

 // create sass file for our sprite gulp.task('svgSpriteSass', function () { return gulp.src(assetsDir + 'i/icons/*.svg') .pipe(svgSprite({ preview: false, selector: "icon-%f", svg: { sprite: 'svg_sprite.html' }, cssFile: '../sass/_svg_sprite.scss', templates: { css: require("fs").readFileSync(assetsDir + 'sass/_sprite-template.scss', "utf-8") } } )) .pipe(gulp.dest(assetsDir + 'i/')); });
      
      





cssFileプロパティで、 scssのどこにファイルを置くか宣言します(それを含めます)。

テンプレートプロパティで、そのテンプレートを取得する場所を宣言します。 私のテンプレートコード:

 .icon { display: inline-block; height: 1em; width: 1em; fill: inherit; stroke: inherit; } {#svg} .{name} { font-size:{height}px; width:({width}/{height})+em; } {/svg}
      
      





次の内容の_svg_sprite.scssを取得します。

 .icon { display: inline-block; height: 1em; width: 1em; fill: inherit; stroke: inherit; } .icon-burger { font-size:64px; width:(66/64)+em; } .icon-check_round { font-size:18px; width:(18/18)+em; }
      
      





コンパイルされたcssは次のようになります。

 .icon { display: inline-block; height: 1em; width: 1em; fill: inherit; stroke: inherit; } .icon-burger { font-size: 64px; width: 1.03125em; } .icon-check_round { font-size: 18px; width: 1em; }
      
      





アイコンのサイズはemで表されるため、font-sizeでアイコンをさらに管理できることに注意してください。

1つのコマンドを実行する最終タスクを作成します。

 gulp.task('svgSprite', ['svgSpriteBuild', 'svgSpriteSass']);
      
      





ページに接続する



そこで、アイコン付きのhtmlファイルと装飾付きのscssファイルを取得しました。 次に、localStorageを介したキャッシュを使用して、ファイルをページに接続します。 このプロセスの詳細については、 localStorageでのSVGスプライトのキャッシュの記事を参照してください。

次のコンテンツのjsファイルを含めます。

 ;( function( window, document ) { 'use strict'; var file = 'i/symbol_sprite.html', revision = 1; if( !document.createElementNS || !document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ).createSVGRect ) return true; var isLocalStorage = 'localStorage' in window && window[ 'localStorage' ] !== null, request, data, insertIT = function() { document.body.insertAdjacentHTML( 'afterbegin', data ); }, insert = function() { if( document.body ) insertIT(); else document.addEventListener( 'DOMContentLoaded', insertIT ); }; if( isLocalStorage && localStorage.getItem( 'inlineSVGrev' ) == revision ) { data = localStorage.getItem( 'inlineSVGdata' ); if( data ) { insert(); return true; } } try { request = new XMLHttpRequest(); request.open( 'GET', file, true ); request.onload = function() { if( request.status >= 200 && request.status < 400 ) { data = request.responseText; insert(); if( isLocalStorage ) { localStorage.setItem( 'inlineSVGdata', data ); localStorage.setItem( 'inlineSVGrev', revision ); } } } request.send(); } catch( e ){} }( window, document ) );
      
      





それだけです。最初のダウンロードがキャッシュされた後、ファイルをページに接続しました。

jaのミックスインにアイコンを埋め込みます。 高速で便利です。

 mixin icon(name,mod) - mod = mod || '' svg(class="icon icon-" + name + ' ' + mod) use(xlink:href="#icon-" + name)
      
      





次に、アイコンを埋め込むために、その名前でmixinを呼び出します。

 +icon('check_round','red_mod') +icon('burger','green_mod')
      
      





結果のhtml:

 <svg class="icon icon-check_round red_mod"> <use xlink:href="#icon-check_round"></use> </svg> <svg class="icon icon-burger green_mod"> <use xlink:href="#icon-burger"></use> </svg>
      
      





ブラウザでページを開きます。







フルサイズのアイコンのサイズと標準色があります。 これを変更します(生成されたファイルではなく、メインファイルで):

 .icon-burger { font-size:3rem; &.green_mod { fill:green; } } .icon-check_round { font-size:3rem; &.red_mod { fill: red; } }
      
      





結果:



以上で、スプライトを介してアイコンを接続するための機能するシステムが得られましたが、もう1つあります。



ぼかし



残念ながら、すべてのデザイナーがピクセルグリッドでアイコンを作成するわけではありません。 この場合、アイコンは「ぼやけ」ます。 イラストレーターからアイコンをエクスポートする場合は、ピクセルグリッドを有効にし、ピクセルグリッドに合わせてアイコンのサイズと位置を調整する必要があります。 既製のsvgファイルで作業する場合は、 iconmoonサービスを使用してそれらを正しく調整してください。



このソリューションの作成を手伝ってくれた@akellaに感謝します。



All Articles