gulpでアイコンフォントを作る方法

アイコンフォントとは、アイコンを画像ではなく文字列として出すことができる手段です。

文字列として扱うことで、色をCSSで簡単に変えられたり、htmlにクラスをつけるだけで表示できたりするのでとっても便利。

私はつい最近までこのアイコンフォントをIcoMoonというサイトで作成していました。

一人で開発する分にはIcoMoonで作成するアイコンで十分満足していたのですが、複数人数でマークアップを進める際にかなりファイル管理が面倒だったので、最近gulpで作成する方法を採用しました。

その作り方のメモです。

バージョン情報

nodeバージョン 16.13.2

gulpバージョン 4.0.2

ディレクトリ構成

.
├gulpfile.js
├ src //開発用フォルダ
│ └ icons //アイコンにしたいsvgを入れるフォルダ
│   ├ XXXXX.svg
│   └ template
│     └ myfont.css //フォント用cssのテンプレート
│
└ dest //出力フォルダ
  └ assets
    ├ css
    │ └ myfont.css //gulpが吐き出すcss
    └ fonts
      ├ myfont.eot //gulpが吐き出すフォントデータ
      ├ myfont.ttf
      └ myfont.woff

ライブラリのインストール

npm install gulp async gulp-iconfont gulp-consolidate gulp-rename lodash --save-dev 

今回鍵となるパッケージは gulp-iconfont です。

gulpで関数作成

const OUTPUT_PATH = "./dest/";
const INPUT_PATH = "./src/";
const gulp = require("gulp");
const async = require('async');
const rename = require("gulp-rename");
const iconfont = require('gulp-iconfont');
const consolidate = require('gulp-consolidate');


//icon font作成
const createIconFont = function (done) {
  var iconStream = gulp.src([INPUT_PATH + 'icons/*.svg'])
    .pipe(iconfont({
      fontName: 'myfont',
      centerHorizontally: true,
      normalize: true,
      fontHeight: 1001
    }));

  async.parallel([
    function handleGlyphs(cb) {
      iconStream.on('glyphs', function (glyphs, options) {
        gulp.src(INPUT_PATH + 'icons/template/myfont.css')
          .pipe(consolidate('lodash', {
            glyphs: glyphs,
            fontName: 'myfont', //フォントファイルの名前
            fontPath: '../fonts/', //出力後フォント用CSSからフォントファイルまでのパス
            className: 'icon', //フォントを使うときのクラス名接頭語
          }))
          .pipe(gulp.dest(OUTPUT_PATH + 'assets/css/'))
          .on('finish', cb);
      });
    },
    function handleFonts(cb) {
      iconStream
        .pipe(gulp.dest(OUTPUT_PATH + 'assets/fonts/'))
        .on('finish', cb);
    }
  ], done);
};

const watchTask = (done) => {
  gulp.watch(INPUT_PATH + "icons/*.svg", createIconFont);
}
exports.default = watchTask;

そのほか追加できるオプションは、gulp-iconfontのドキュメントから確認できます。

テンプレートCSSの作成

@font-face {
  font-family: "<%= fontName %>";
  src: url('<%= fontPath %><%= fontName %>.eot');
  src: url('<%= fontPath %><%= fontName %>.eot?#iefix') format('eot'),
      url('<%= fontPath %><%= fontName %>.woff') format('woff'),
      url('<%= fontPath %><%= fontName %>.ttf') format('truetype'),
      url('<%= fontPath %><%= fontName %>.svg#<%= fontName %>') format('svg');
  font-weight: normal;
  font-style: normal;
}
[class*="<%= className %>-"] {
  display: inline-block;
  font-family: "<%= fontName %>";
  font-style: normal;
  font-weight: normal;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
<% _.each(glyphs, function(glyph) { %>.<%= className %>-<%= glyph.name %>:before { content: "\<%= glyph.unicode[0].charCodeAt(0).toString(16).toUpperCase() %>" }
<% }); %>

watchタスク実行

これで準備が整ったので、下記のコマンドを実行し、”/sec/icons/”フォルダ内にSVGが投入されれば自動でコンパイルされます。

npm run gulp

実際にHTMLで使うときはgulpファイルで設定した「[接頭語]-[SVGファイル名]」というクラスをタグに付与していきます。

例)"arrow_down.svg"を入れた場合のクラス名

<p>ダミーテキスト<span class="icon-arrow_down"></span></p>

ブラウザでの表示

サンプル画像

参考サイト

https://www.npmjs.com/package/gulp-iconfont

https://hirakublog.com/gulp-iconfont/