[Gulp]SVGスプライト画像を自動で生成。複数のSVGアイコンを一つにまとめて背景画像にも対応。


SVG spritegulpプラグインを利用し、複数のSVGアイコンからスプライト画像を生成するタスクを設定してみました。
自動処理なのでアイコンの追加・削除・更新を検知して都度まとめてくれます。
<svg>タグで書いてもよし、CSSのbackgroundで背景として表示してもよし。

※gulpやnpmのインストールはすでに済んでいる前提です。

検証環境

  • nodeバージョン:8.12.0
  • npmバージョン:5.3.0
  • gulpバージョン:CLI version 3.9.1

ディレクトリ構造

_src/images/svg-sprite/ ディレクトリからSVGアイコンを取得し、 _dest ディレクトリ内にスプライト画像と背景指定用のcssファイルをアウトプットします。

↓アウトプットされたファイル例

各種設定

package.json

package.json
{
  "name": "svg-sprite",
  "version": "1.0.0",
  "description": "svg-sprite gulp task",
  "devDependencies": {
    "gulp": "^3.9.1",
    "gulp-svg-sprite": "^1.5.0"
  },
  "private": true
}

namedescription は任意のテキストで設定してください。

gulpfile.js

gulpfile.jsの設定は完全に理解していない部分もあるので、正確な書き方は公式ドキュメントを見ていただければと思います。

gulpfile.js
var gulp = require('gulp'),
svgSprite = require('gulp-svg-sprite');

// タスク
gulp.task('sprite', function() {
  return gulp.src('_src/images/svg-sprite/*.svg') // 元となるSVGアイコンのパス(*.svg で全SVGを対象に)
    .pipe(svgSprite({
      mode: {
        symbol: {
          // スプライト画像を置くディレクトリ名。指定しないとデフォルト設定(svg)に。
          dest: 'images',

          // スプライト画像のファイル名
          sprite: 'sprite.svg',

          // スプライト画像のプレビュー用HTMLが欲しい人はこちらも記述してください。
          // 任意の場所とファイル名を指定してください。
          example: {
            dest: '../css/svg-sprite-preview/sprite.html',
          }
        },
      } // mode
    }))

    // 書き出し先
    .pipe(gulp.dest('_dest')),

  // 背景用スプライト画像を指定
  gulp.src('_src/images/svg-sprite-bg/*.svg')
    .pipe(svgSprite({
      mode: {
        css: {
          // 背景用スプライト画像のファイル名を指定
          // ただし自動で接尾辞がつく
          sprite: '../images/sprite-bg.svg',

          // class名の接頭辞を指定。なぜか頭にドットが必要(例).icon_home
          prefix: '.icon_%s',

          // サイズ指定用classの接尾辞(例).icon_home_dims
          dimensions: "_dims",

          render: {
            // CSSファイル名を指定
            css: {
              dest: 'sprite.css',
            },

            // SCSSファイルも生成する場合はこちらも記述
            // 相対パスで _src ディレクトリ内を指定
            scss: {
              dest: '../../_src/sass/_sprite.scss',
            }
          },

          // スプライト画像のプレビュー用ページが欲しい場合はこちらも記述
          // 任意の場所とファイル名を指定
          example: {
            dest: 'svg-sprite-preview/sprite-bg.html',
          }
        }, // css

      } // mode
    }))

    // 書き出し先
    .pipe(gulp.dest('_dest'));
});


// 自動処理の設定
gulp.task('default', function() {
  gulp.watch('_src/images/{,**/}*.svg',['sprite']);
});

gulpを実行

以上の設定ファイルを作成しnpmインストールも行ったら、以下のコマンドでgulpを実行してください。

gulp sprite

これで _dest ディレクトリ内に

  • css/
    • sprite.css
    • svg-sprite-preview/
      • sprite-bg.html
      • sprite.html
  • images/
    • sprite.svg
    • sprite-bg-7b55828d.svg

というファイルが、さらに_src ディレクトリ内に

  • _src/
    • sass/
      • _sprite.scss

と、それぞれファイルが追加されています。

HTMLの設定

実際にスプライト画像を使ってアイコンを表示するには以下のように書きます。

head

<head>
  <link rel="stylesheet" type="text/css" href="css/sprite.css">

  <!-- SVG非対応ブラウザ用ポリフィル -->
  <script src="js/svg4everybody.js"></script>
  <script>svg4everybody();</script>
</head>

SVG非対応ブラウザ用ポリフィルはsvg4everybodyを利用しています。

body

svgタグを使って表示

元のSVGアイコンhome.svg を表示する場合は

<svg class="icon">
  <use xlink:href="images/sprite.svg#home" />
</svg>

というように、<use xlink:href=" の値が 〜.svg#元のファイル名 となります。

サイズや色の変更するはCSSを使います。

.icon {
  width: 32px;
  height: 32px;
  fill: red;
}

ブラウザの検証機能で見るとこのようになります。

backgroundを使って表示

_dest 内の sprite.css のclassを使います。

sprite.css
.icon_heart {
  background: url("../images/sprite-bg-7b55828d.svg") 0 100% no-repeat;
}

.icon_heart_dims {
  width: 32px;
  height: 32px;
}

gulpfile.js でclass名の接頭辞を指定しているので、
.icon_元のファイル名.icon_元のファイル名_dims をセットで使用します。

<span class="icon_heart icon_heart_dims"></span>

ブラウザの検証機能で見るとこのようになります。

ポリフィルを使うことでIE11でも問題なく表示されます。

プレビュー用ページ

gulpfile.js

gulpfile.js
example: {
  dest: 'svg-sprite-preview/sprite-bg.html',
}

このように書きましたが、これを書いておくことでSVGスプライト画像のプレビュー用ページが生成されます。

このページを見ればアイコン名がひと目で分かるので、<svg> やclass名で指定する際にとても便利です。

補足

background を使う際のサイズ変更はCSSのtransform: scale(*); を使うしか無いようです。
※参考「アイコンファイルをラクラク管理!『SVG sprite』を使いこなそう

また、背景で使うとfillで色を変更することが出来ないので、背景用の色でアイコンを用意しておく必要があります。自分が知らないだけで変更方法があるのかもしれませんが…。


以上です。

<svg> による表示と、background 指定の両方に対応するスプライト画像生成が上手くいかずハマってしまったことがあったので、このSVG spriteのgulpプラグインで両方に対応出来るのは嬉しいですね。

参考になりましたら幸いです。


下記のページを参考にさせていただきました。ありがとうございます。

▼SVG sprites
https://github.com/jkphl/gulp-svg-sprite

▼SVG for Everybody
https://github.com/jonathantneal/svg4everybody

▼アイコンファイルをラクラク管理!『SVG sprite』を使いこなそう
http://liginc.co.jp/404217

▼svg-spriteで無駄の無いSVGスプライトを生成する
https://design.dena.com/engineering/svg-sprite/