Hiswe / gulp-svg-symbols

Convert svg files to symbols
https://www.npmjs.com/package/gulp-svg-symbols
MIT License
169 stars 18 forks source link

gulp-svg-symbols

npm version Build Status

gulp-svg-symbols is a minimal plugin for gulp.
It converts a bunch of svg files to a single svg file containing each one as a symbol.
See css-trick for more details.

Install

npm install --save-dev gulp-svg-symbols

Example

In your gulpfile.js:

const gulp = require('gulp')
const svgSymbols = require('gulp-svg-symbols')

gulp.task(`sprites`, function() {
  return gulp
    .src(`assets/svg/*.svg`)
    .pipe(svgSymbols())
    .pipe(gulp.dest(`assets`))
})

In your HTML, you first have to reference the SVG
then:

<svg role="img" class="github">
  <use xlink:href="#github"></use>
</svg>

Options

You can override the default options by passing an object as an argument to svgSymbols()

Basics

id and class

type: function or string
default: '%f' and '.%f'

Text templates for generating symbols id & icon class
%f is the speakingurled file name placeholder.
See more about the name in the slug option

fontSize

type: number
default: 0

This option lets you define a base font.
If it's superior to 0, then the sizes in your CSS file will be in em else sizes are provided with px.

title

type: boolean or function or string
default: false

Specify whether or not you want to add a missing title tag in your SVG symbols.
It should be better for accessibility.
It takes a text template (like for id/classname):

title: `%f icon`

svgAttrs

type: object
default: {class: null, xmlns: 'http://www.w3.org/2000/svg'}

Specify attributes for the <svg> container tag in the default SVG template.

{
  class: `svg-icon-lib`,
  'aria-hidden': `true`,
  style: `position: absolute;`,
  'data-enabled': true,
}

output:

<svg xmlns="http://www.w3.org/2000/svg" class="svg-icon-lib" aria-hidden="true" style="position: absolute;" data-enabled>

notes:

slug

type: object or function
default: {}

In order to have nice ids in the template and to keep the gulp task quite simple, gulp-svg-symbols use speakingurl.

You can pass a speakingurl's config here:

gulp.src(`*.svg`).pipe(
  svgSymbols({
    slug: {
      separator: `_`,
    },
  })
)

You can also provide a custom function which should return a string:

gulp.src(`*.svg`).pipe(
  svgSymbols({
    slug: function(name) {
      return name.replace(/\s/g, `-`)
    },
  })
)

Or if you want to use gulp-rename:

gulp
  .src(`*.svg`)
  .pipe(rename(/* gulp rename options*/))
  .pipe(
    svgSymbols({
      slug: name => name,
    })
  )

templates

type: array of string
default: ['default-svg', 'default-css']

gulp-svg-symbols comes with some default templates.

You can control which file are generated by specifying only the templates to keep:

templates: [`default-svg`]

will output only the SVG file.

Here is the list of all provided templates:

More details about the build-in templates can be found in the TEMPLATES.md file

CSS generation

You can deactivate CSS output by removing the CSS template from the template array.
See templates option for more details.

warn

default: true

Disable plugin warn messages (like: missing viewBox & depreciation warnings).

Advanced

templates

Specify your own templates by providing an absolute path:

templates: [
  path.join(__dirname, `path/to/my/template.less`),
  path.join(__dirname, `path/to/another/template.js`),
  // You can still access to default templates by providing:
  `default-svg`,
  `default-css`,
  `default-demo`,
]
{
  svgAttrs: {/*  the same object you can pass in configuration */ },
  defs: `string`,
  icons: [{
    id: `string`,
    class: `.string`,
    width: `a number as a string with a unit`,
    height: `a number as a string with a unit`,
    style: `string if exists`,
    svg: {
      name: `string (svg filename without extension)`,
      id: `string`,
      width: `number`,
      height: `number`,
      content: `the svg markup as a string`,
      viewBox: `string`,
      originalAttributes: {
        /* every attributes before processing them */
      },
    },
  }, {/*…*/}, ],
}

transformData

With the ability to provide custom templates, you also have the ability to configure custom data.

transformData: function(svg, defaultData, options) {
  /******
  svg is same object as the one passed to the templates (see above)

  defaultData are the ones needed by default templates
  see /lib/get-default-data.js

  options are the one you have set in your gulpfile,
    minus templates & transformData
  *******/

  return {
    // Return every datas you need
    id:         defaultData.id,
    class:      defaultData.class,
    width:      `${svg.width}em`,
    height:     `${svg.height}em`
  };
}

In your templates, svg original data are accessible in icon.svg.
Of course default templates need defaultData.

Other observations

If you want to include the SVG symbols directly in the DOM (i.e. no external reference) and mask it, a secure way of hiding it could be achieved in this way:

.svg-icon-lib {
  border: 0 !important;
  clip: rect(0 0 0 0) !important;
  height: 1px !important;
  margin: -1px !important;
  overflow: hidden !important;
  padding: 0 !important;
  position: absolute !important;
  width: 1px !important;
}

A simple display: none will mess with defs rendering (gradients and so on…)

Other stuff

Rendering caveats

SVG can have rendering issues if:

An example has been made to show all those issues resolved inside the svgContainingIdenticalId.

npm run svg-containing-identical-id to test.

Migrating

See MIGRATING.md

More examples

Go in the examples folder, then npm install && npm run list.
You will have a list of all task examples there

Usefull frontend lib

Thanks

Credits

Alternatives