fontawesome-svg-sprite-generator
v1.0.2
Published
Generate custom SVG sprites for a selected number of Font Awesome 5 icons
Downloads
642
Maintainers
Readme
fontawesome-svg-sprite-generator
A simple Node.js library that generates custom SVG sprite files for a selected number of Font Awesome 5 icons.
SVG Sprites make it easy to use Font Awesome SVG icons without loading any JavaScript code at runtime. They work great across all modern browsers* and are simple to use. However, Font Awesome only provides predefined SVG sprite files that include all icons of an icon pack. In most cases, only a small number of the icons are actually used on the website. fontawesome-svg-sprite-generator makes it simple to generate SVG Sprites using only the icons you need.
* Note: IE 11 is unable to load SVG symbols from external (i.e. not inlined) SVG sprites. svg4everybody exists as a simple polyfill if you still care about supporting it.
Contents
Introduction
Generated SVG sprites will look like the following (prettified):
<?xml version="1.0" encoding="UTF-8"?>
<!--
Font Awesome Free by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="fab-fa-font-awesome" viewBox="0 0 448 512">
<path fill="currentColor" d="M397.8 32H50.2C22.7 ..."></path>
</symbol>
</svg>
Each SVG icon is included as <symbol>
with an
unique ID in the SVG file. It can then be referenced in HTML as follows:
<svg role="img" class="svg-inline--fa fa-w-14">
<title>Font Awesome</title>
<use href="sprite.svg#fab-fa-font-awesome"></use>
</svg>
Icons must be styled using CSS to give them the correct size. This can be either done manually, or by loading the Font Awesome SVG-with-JS CSS stylesheet and applying the correct classes (as done above). See Styling for details.
Installation
Note: Node.js 8 or newer is required.
npm install fontawesome-svg-sprite-generator
You also need to install the icon packs you would like to use from NPM (see Importing Icons ("Package names") for details). Examples for free packages:
npm install @fortawesome/free-solid-svg-icons
npm install @fortawesome/free-regular-svg-icons
npm install @fortawesome/free-brands-svg-icons
Usage
fontawesome-svg-sprite-generator uses the Font Awesome API to generate SVG icons and bundles them to a single SVG Sprite. It uses parts of the code that would normally run in the browser. That way, you can still use most features of SVG-with-JS, except that it is evaluated at build time and not at runtime.
As a quick start, here is a simple example that creates a SVG sprite with only fa-font-awesome
and writes it to
sprite.svg
.
const fs = require('fs');
const fab = require('@fortawesome/free-brands-svg-icons');
const faSvgSprite = require('fontawesome-svg-sprite-generator');
const sprite = faSvgSprite.generate([
fab.faFontAwesome
]);
// sprite.svg contains the raw SVG code for the generated sprite
fs.writeFileSync('sprite.svg', sprite.svg);
In this case, the symbol ID fab-fa-font-awesome
is automatically generated based on the icon name.
Selecting icons
Icons can be selected using a simple list. In this case, the symbol IDs will be generated automatically:
const fas = require('@fortawesome/free-solid-svg-icons');
const sprite = faSvgSprite.generate([
fas.faPlus,
fas.faCircle
]);
It is also possible to set symbol IDs manually by using an object instead:
const fas = require('@fortawesome/free-solid-svg-icons');
const sprite = faSvgSprite.generate({
plus: fas.faPlus,
circle: fas.faCircle
});
You can also lookup icons from the Icon Library:
const fa = require('@fortawesome/fontawesome-svg-core');
const fas = require('@fortawesome/free-solid-svg-icons');
fa.library.add(fas);
const sprite = faSvgSprite.generate([
{ prefix: 'fas', iconName: 'plus' },
{ prefix: 'fas', iconName: 'circle' }
]);
Styling
Unfortunately, scaling the SVG icons does not quite work as expected by default. To preserve the aspect ratio of the icons,
you will either need to copy the viewBox
of the icon on each usage, or set both width and height manually using CSS.
Alternatively, you can re-use Font Awesome's CSS classes from the SVG-with-JS stylesheet.
Using Font Awesome's stylesheet
You can re-use the CSS classes that would normally be set automatically when using Font Awesome's SVG-with-JS framework. However, when using SVG sprites you have to add the CSS classes on each usage manually:
Load Font Awesome's SVG-with-JS stylesheet. It is available in different places:
- In the "For the Web" download on fontawesome.com (
css/svg-with-js.css
, minified) - In the
@fortawesome/fontawesome-free
NPM package (css/svg-with-js.css
, minified) - In the
@fortawesome/fontawesome-svg-core
NPM package (styles.css
, not minified)
- In the "For the Web" download on fontawesome.com (
Add the CSS classes to each usage of the icon:
svg-inline--fa
plus one of thefa-w-<number>
CSS classes (see below):<svg class="svg-inline--fa fa-w-14"> <use href="sprite.svg#fab-fa-font-awesome"></use> </svg>
The
<number>
in thefa-w-<number>
class depends on the aspect ratio of the icon. The easiest way to find out the correct classes to use is to take a look at the Symbol Attributes provided by fontawesome-svg-sprite-generator:const sprite = faSvgSprite.generate(...); console.log(sprite.attributes); /* Prints: { 'fab-fa-font-awesome': { class: 'svg-inline--fa fa-font-awesome fa-w-14', viewBox: '0 0 448 512' } } */
class
contains the CSS classes SVG-with-JS would apply. (The icon specificfa-font-awesome
CSS class doesn't seem to have any effect currently...)If you really would like to know: SVG-with-JS calculates them using
(width / height) * 16
(rounded up) where width and height are taken from theviewBox
of the icon:viewBox="0 0 448 512"
results in(448 / 512) * 16 = fa-w-14
as used above.
You can make use of many additional styles as shown in the Styling section of the Font Awesome documentation (e.g. making the icons larger or setting a fixed width...)
Using viewBox
and custom CSS
Alternatively, you can copy the viewBox
to the <svg>
element of each usage to make the browser aware of the correct
aspect ratio of the icon. That way, the icon will scale correctly even if you define only one dimension (you should
probably do this with CSS classes instead of inline attributes...):
<svg viewBox="0 0 448 512" style="height: 1em">
<use href="sprite.svg#fab-fa-font-awesome"></use>
</svg>
As with the CSS classes, the viewBox
is specific to each icon. You can either lookup the <symbol>
for the icon in the
generated SVG sprite and copy its viewBox
, or take another look at the Symbol Attributes provided by
fontawesome-svg-sprite-generator:
const sprite = faSvgSprite.generate(...);
console.log(sprite.attributes);
/* Prints:
{ 'fab-fa-font-awesome':
{ class: 'svg-inline--fa fa-font-awesome fa-w-14',
viewBox: '0 0 448 512' } }
*/
Setting width and height manually
Obviously, you can also do everything yourself and just set width
and height
manually using CSS.
In this case, you need to be really careful to preserve the correct aspect ratio, though...
Options
There are a number of options that can be used to customize the generated SVG sprite.
They should be passed as additional argument to the generate
method:
const options = {
// Exclude XML declaration (e.g. `<?xml version="1.0" encoding="UTF-8"?>`)
//xmlDeclaration: false,
// Change license attribution within the generated SVG sprite file.
//license: ' Some other license text ',
// Remove license attribution entirely
//license: '',
};
const sprite = faSvgSprite.generate(/* icons... */, options);
The license
option may be relevant when using fontawesome-svg-sprite-generator with Font Awesome Pro: By default,
the license attribution for Font Awesome Free is included in the generated SVG document.
Build System Integration
Gulp
fontawesome-svg-sprite-generator can be easily integrated into Gulp builds. Since usage pretty much only involves writing the generated SVG into a file, I decided against writing yet another Gulp plugin and provide instructions here instead.
Basic Usage
const fs = require('fs');
const fab = require('@fortawesome/free-brands-svg-icons');
const faSvgSprite = require('fontawesome-svg-sprite-generator');
gulp.task('icons', done => {
const sprite = faSvgSprite.generate([fab.faFontAwesome]);
fs.writeFile('sprite.svg', sprite.svg, done);
});
Transforming SVG with streams
A bit more effort is needed if you would like to transform the generated SVG with other Gulp plugins:
const stream = require('stream');
const File = require('vinyl');
const fab = require('@fortawesome/free-brands-svg-icons');
const faSvgSprite = require('fontawesome-svg-sprite-generator');
gulp.task('icons', () => {
const sprite = faSvgSprite.generate([fab.faFontAwesome]);
return new stream.Readable({
objectMode: true,
read() {
this.push(new File({
path: 'sprite.svg',
contents: new Buffer(sprite.svg),
});
this.push(null);
}
})
.pipe(...)
.pipe(gulp.dest('dist'));
});
Symbol Attributes
If you would like to serialize the Symbol Attributes into an additional JSON file, using Promises is easier:
const util = require('util');
const writeFile = util.promisify(require('fs').writeFile);
const fab = require('@fortawesome/free-brands-svg-icons');
const faSvgSprite = require('fontawesome-svg-sprite-generator');
gulp.task('icons', () => {
const sprite = faSvgSprite.generate([fab.faFontAwesome]);
return Promise.all([
writeFile('sprite.svg', sprite.svg),
writeFile('sprite-attributes.json', JSON.stringify(sprite.attributes)),
]);
});
Advanced Usage
Symbol Attributes
Figuring out the correct CSS classes or viewBox
to use can be painful (see Styling). To simplify this, an additional
object of Symbol Attributes is exposed when generating a sprite. It maps the unique IDs of the symbols to the correct
set of attributes needed for each usage of the icon. Serialized into a JSON file, it can be plugged into any templating
language to avoid having to lookup the attributes manually.
const fs = require('fs');
const fab = require('@fortawesome/free-brands-svg-icons');
const faSvgSprite = require('fontawesome-svg-sprite-generator');
const sprite = faSvgSprite.generate([
fab.faFontAwesome
]);
// sprite.svg contains the raw SVG code for the generated sprite
fs.writeFileSync('sprite.svg', sprite.svg);
// sprite-attributes.json contains the Symbol Attributes for the generated sprite
fs.writeFileSync('sprite-attributes.json', JSON.stringify(sprite.attributes));
Results in:
{
"fab-fa-font-awesome": {
"class": "svg-inline--fa fa-font-awesome fa-w-14",
"viewBox": "0 0 448 512"
}
}
Example code for integration into some template languages (feel free to contribute!):
- Coming Soon
Icon Options
The Font Awesome API provides a couple of options that affect the generation of SVG code for the icon. You can use them to apply "Power Transforms", mask icons or setting an icon title for Accessibility.
Check the icon()
Font Awesome API documentation for a list
of possible options (starting with "Using a transform").
Options are provided by using an array/tuple in place of the icon lookup:
const fab = require('@fortawesome/free-brands-svg-icons');
const sprite = faSvgSprite.generate({
'fontawesome-transformed': [fab.faFontAwesome, {
transform: {
rotate: 90
}
}],
});
Note: These transforms will be applied at build time; therefore you need to embed all transformed icons manually into the SVG sprite. It might make more sense to use CSS to apply some of these transforms...
Accessibility
The Icon Options above can be used to define a title for the icon that will be included as fallback description for the icon in the generated SVG document:
const fab = require('@fortawesome/free-brands-svg-icons');
const sprite = faSvgSprite.generate({
fontawesome: [fab.faFontAwesome, {
title: 'Font Awesome'
}],
});
More important, however, is correctly annotating the usage of the icons in the HTML code:
Decorative Icons: If your icon should be ignored by screen readers (e.g. because there is text next to it), add either
role="presentation"
oraria-hidden
to the surrounding SVG element:<svg role="presentation" class="svg-inline--fa fa-w-14"> <use href="sprite.svg#fab-fa-font-awesome"></use> </svg>
Standalone Icons: If alternative text should be read out by screen readers, add
role="img"
and define a meaningful<title>
for the icon:<svg role="img" class="svg-inline--fa fa-w-14"> <title>Font Awesome</title> <use href="sprite.svg#fab-fa-font-awesome"></use> </svg>
Contributing
fontawesome-svg-sprite-generator is written in TypeScript.
npm run build
: Compile TypeScript into JavaScript (in thedist
folder)npm test
: Run the unit tests to ensure everything is still working
License
fontawesome-svg-sprite-generator is licensed under the MIT License. This is not an official Fort Awesome project.