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.
npm install --save-dev gulp-svg-symbols
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
You can override the default options by passing an object as an argument to svgSymbols()
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
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.
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`
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
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,
})
)
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
You can deactivate CSS output by removing the CSS template from the template array.
See templates option for more details.
default: true
Disable plugin warn messages (like: missing viewBox & depreciation warnings).
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
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
.
- 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…)
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.
See MIGRATING.md
Go in the examples folder, then npm install && npm run list
.
You will have a list of all task examples there
- svg4everybody leverage external SVG for browser which doesn't support it
- Florens Verschelde for the usefull insights and PR
- Chris Coyier for the trick
- Shaky Shane for the gulp-svg-sprites plugin
- FWeinb for the grunt-svgstore plugin