gulp-svg-symbols
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>
- class is the one generated in the CSS file
- xlink:href is the symbol id in the SVG file
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:
- this is how you can add a
class
to the generated SVG - any string or numeric attribute will be rendered
- boolean attributes will just toggle the attribute without any value. If you need to render the boolean as a value just pass it as a string
- the attribute
xmlns:xlink="http://www.w3.org/1999/xlink"
will be added automatically if anyxlink:
is found in the SVG content
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:
- default-svg: the bundle of SVG
- default-css: a CSS file gathering all sizes and additional styles
- default-demo: a demo page which provide an overview of every symbols + a way to copy/paste easily the symbol SVG code
- default-vue: a vue component
- default-css-var: same as the CSS, but all sizes will be also declared as CSS Custom Properties
- default-scss: same as the CSS, but sizes will be declared as SCSS variables
- default-stylus: same as the CSS, but sizes will be declared as Stylus variables
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`,
]
- template engine is lodash.
- the output files will have the same name & extension as your files.
- every template will have acces to those datas:
{
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 */
},
},
}, {/*โฆ*/}, ],
}
- and also 2 helpers functions
attributesToString( object )
render an object as a string of attributessvgdataToSymbol( iconData )
render an icon data object to a stringed symbol
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 manipulate your icons files, use gulp-cheerio
- If you want to optimize your icons files or the SVG output, use gulp-svgmin (using SVGO)
- If you want to change the generated files name, again use gulp-rename
- If you want different destination for the files, use gulp-if
- Unlike gulp-svg-sprites there is no way to add padding to SVG files.
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:
- multiple
<defs>
have the same ids.
Use gulp-svgmin to fix that. <clipPath>
and<mask>
aren't staying inside<defs>
tags.
Move those tags inside the<defs>
tags. Manually or programmatically (easy to do with gulp-cheerio)
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
- svg4everybody leverage external SVG for browser which doesn't support it
Thanks
- Florens Verschelde for the usefull insights and PR
Credits
- Chris Coyier for the trick
- Shaky Shane for the gulp-svg-sprites plugin
- FWeinb for the grunt-svgstore plugin