Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
svg-sprite
Advanced tools
SVG sprites & stacks galore — A low-level Node.js module that takes a bunch of SVG files, optimizes them and bakes them into SVG sprites of several types along with suitable stylesheet resources (e.g. CSS, Sass, LESS, Stylus, etc.)
The svg-sprite npm package is a powerful tool for creating SVG sprites. It allows you to combine multiple SVG files into a single file, which can then be used to optimize the delivery and performance of SVG assets in web applications. The package supports various modes of sprite generation, including symbol, stack, and CSS sprites, and provides a range of configuration options to customize the output.
Symbol Sprite Mode
This feature allows you to create a symbol sprite, which is a single SVG file containing multiple symbols. Each symbol can be referenced individually using the <use> element in your HTML.
const svgSprite = require('svg-sprite');
const config = {
mode: {
symbol: {
dest: 'out',
sprite: 'symbol-sprite.svg'
}
}
};
svgSprite(config).then(() => console.log('Symbol sprite created!'));
CSS Sprite Mode
This feature allows you to create a CSS sprite, which is a single SVG file that can be used with CSS to display individual icons. The package can also generate the corresponding CSS file to use the sprite.
const svgSprite = require('svg-sprite');
const config = {
mode: {
css: {
dest: 'out',
sprite: 'css-sprite.svg',
render: {
css: true
}
}
}
};
svgSprite(config).then(() => console.log('CSS sprite created!'));
Stack Sprite Mode
This feature allows you to create a stack sprite, which is a single SVG file containing multiple stacked SVG elements. Each element can be referenced individually using the <use> element in your HTML.
const svgSprite = require('svg-sprite');
const config = {
mode: {
stack: {
dest: 'out',
sprite: 'stack-sprite.svg'
}
}
};
svgSprite(config).then(() => console.log('Stack sprite created!'));
svg-sprite-loader is a webpack loader that allows you to import SVG files as symbols in a sprite. It is similar to svg-sprite in that it helps optimize SVG delivery, but it is specifically designed to work with webpack, making it a good choice for projects that use webpack for module bundling.
gulp-svg-sprite is a Gulp plugin for creating SVG sprites. It offers similar functionality to svg-sprite but is designed to be used within a Gulp build process. This makes it a good option for projects that use Gulp for task automation.
svgstore is a simple tool for creating SVG sprites. It is less feature-rich compared to svg-sprite but provides a straightforward way to combine multiple SVG files into a single sprite. It is a good choice for projects that need a lightweight solution for SVG sprite generation.
svg-sprite is a low-level Node.js module that takes a bunch of SVG files, optimizes them and bakes them into SVG sprites of several types:
<view>
elements, useful for foreground images as well,<defs>
element,<symbol>
elementIt comes with a set of Mustache templates for creating stylesheets in good ol' CSS or one of the major pre-processor formats (Sass, Less and Stylus). Tweaking the templates or even adding your own custom output format is really easy, just as switching on the generation of an HTML example document along with your sprite.
For an up-to-date list of browsers supporting SVG in general respectively SVG fragment identifiers in particular (required for <defs>
and <symbol>
sprites as well as SVG stacks) please refer to caniuse.com.
Being a low-level library with support for Node.js streams, svg-sprite doesn't take on the part of accessing the file system (i.e. reading the source SVGs from and writing the sprites and CSS files to disk). If you don't want to take care of this stuff yourself, you might rather have a look at the available wrappers for Grunt (grunt-svg-sprite) and Gulp (gulp-svg-sprite). svg-sprite is also the foundation of the iconizr project, which serves high-quality SVG based CSS icon kits with PNG fallbacks.
To install svg-sprite globally, run:
npm install svg-sprite -g
Crafting a sprite with svg-sprite typically follows these steps:
The procedure is the very same for all supported sprite types («modes»).
const fs = require('fs');
const path = require('path');
const SVGSpriter = require('svg-sprite');
// Create spriter instance (see below for `config` examples)
const spriter = new SVGSpriter(config);
// Add SVG source files — the manual way ...
spriter.add('assets/svg-1.svg', null, fs.readFileSync('assets/svg-1.svg', 'utf-8'));
spriter.add('assets/svg-2.svg', null, fs.readFileSync('assets/svg-2.svg', 'utf-8'));
/* ... */
// Compile the sprite
spriter.compile((error, result) => {
/* Write `result` files to disk (or do whatever with them ...) */
for (const mode in result) {
for (const resource in result[mode]) {
fs.mkdirSync(path.dirname(result[mode][resource].path), { recursive: true });
fs.writeFileSync(result[mode][resource].path, result[mode][resource].contents);
}
}
});
// Or compile the sprite async
const { result } = await spriter.compileAsync();
/* Write `result` files to disk (or do whatever with them ...) */
for (const mode in result) {
for (const resource in result[mode]) {
fs.mkdirSync(path.dirname(result[mode][resource].path), { recursive: true });
fs.writeFileSync(result[mode][resource].path, result[mode][resource].contents);
}
}
As you can see, big parts of the above are dealing with disk I/O. In this regard, you can make your life easier by using the Grunt or Gulp wrappers instead of the standard API.
Of course you noticed the config
variable passed to the constructor in the above example. This is svg-sprite's main configuration — an Object
with the following properties:
{
dest: <String>, // Main output directory
log: <String|Logger>, // Logging verbosity or custom logger
shape: <Object>, // SVG shape configuration
svg: <Object>, // Common SVG options
variables: <Object>, // Custom templating variables
mode: <Object> // Output mode configurations
}
If you don't provide a configuration object altogether, svg-sprite uses built-in defaults for these properties, so in fact, they are all optional. However, you will need to enable at least one output mode (mode
property) to get reasonable results (i.e. a sprite of some type).
Many configuration properties (all except mode
) apply to all sprites created by the same spriter instance. The default values are:
// Common svg-sprite config options and their default values
const config = {
dest: '.', // Main output directory
log: null, // Logging verbosity (default: no logging)
shape: { // SVG shape related options
id: { // SVG shape ID related options
separator: '--', // Separator for directory name traversal
generator: function () { /*...*/ }, // SVG shape ID generator callback
pseudo: '~' // File name separator for shape states (e.g. ':hover')
},
dimension: {// Dimension related options
maxWidth: 2000, // Max. shape width
maxHeight: 2000, // Max. shape height
precision: 2, // Floating point precision
attributes: false, // Width and height attributes on embedded shapes
},
spacing: { // Spacing related options
padding: 0, // Padding around all shapes
box: 'content' // Padding strategy (similar to CSS `box-sizing`)
},
transform: ['svgo'], // List of transformations / optimizations
meta: null, // Path to YAML file with meta / accessibility data
align: null, // Path to YAML file with extended alignment data
dest: null // Output directory for optimized intermediate SVG shapes
},
svg: { // General options for created SVG files
xmlDeclaration: true, // Add XML declaration to SVG sprite
doctypeDeclaration: true, // Add DOCTYPE declaration to SVG sprite
namespaceIDs: true, // Add namespace token to all IDs in SVG shapes
namespaceIDPrefix: '', // Add a prefix to the automatically generated namespaceIDs
namespaceClassnames: true, // Add namespace token to all CSS class names in SVG shapes
dimensionAttributes: true // Width and height attributes on the sprite
},
variables: {} // Custom Mustache templating variables and functions
}
Please refer to the configuration documentation for details.
At the moment, svg-sprite supports five different output modes (i.e. sprite types), each of them has its own characteristics and use cases. It's up to you to decide which sprite type is the best choice for your project. The mode
option controls which sprite types are created. You may enable more than one output mode at a time — svg-sprite will happily create several sprites in parallel.
To enable the creation of a specific sprite type with default values, simply set the appropriate mode
property to true
:
const config = {
mode: {
css: true, // Create a «css» sprite
view: true, // Create a «view» sprite
defs: true, // Create a «defs» sprite
symbol: true, // Create a «symbol» sprite
stack: true // Create a «stack» sprite
}
}
To further configure a sprite, pass in an object with configuration options:
// «symbol» sprite with CSS stylesheet resource
const config = {
mode: {
css: {
// Configuration for the «css» sprite
// ...
}
}
}
Many mode
properties are shared between the different sprite types, but there are also type specific options. Please refer to the configuration documentation for a complete list of settings.
// Common mode properties
const config = {
mode: {
<mode>: {
dest: "<mode>", // Mode specific output directory
prefix: "svg-%s", // Prefix for CSS selectors
dimensions: "-dims", // Suffix for dimension CSS selectors
sprite: "svg/sprite.<mode>.svg", // Sprite path and name
bust: true || false, // Cache busting (mode dependent default value)
render: { // Stylesheet rendering definitions
/* -------------------------------------------
css: false, // CSS stylesheet options
scss: false, // Sass stylesheet options
less: false, // LESS stylesheet options
styl: false, // Stylus stylesheet options
<custom>: ... // Custom stylesheet options
------------------------------------------- */
},
example: false // Create an HTML example document
}
}
}
Foreground image sprite with <symbol>
elements (for being <use>
d in your HTML source):
// «symbol» sprite with CSS stylesheet resource
const config = {
mode: {
symbol: { // Create a «symbol» sprite
inline: true // Prepare for inline embedding
}
}
}
Traditional CSS sprite with a Sass stylesheet:
// «css» sprite with Sass stylesheet resource
const config = {
mode: {
css: { // Create a «css» sprite
render: {
scss: true // Render a Sass stylesheet
}
}
}
}
<defs>
sprite, <symbol>
sprite and an SVG stack all at once:
// «defs», «symbol» and «stack» sprites in parallel
const config = {
mode: {
defs: true,
symbol: true,
stack: true
}
}
mode
-less run, returning the optimized SVG shapes only:
// Just optimize source SVG files, create no sprite
const config = {
shape: {
dest: 'path/to/out/dir'
}
}
Depending on your particular configuration, svg-sprite creates a lot of files that partly refer to each other. Several configuration options are controlling the exact location of each file, and you are well advised to spend a moment understanding how they interrelate with each other.
Relative destination paths refer to their ancestors as shown in the following scheme, with the current working directory being the ultimate base.
Destination option Default Comment
---------------------------------------------------------------------------------------------
cwd $ <dest>/ . Main output directory
<mode.css.dest>/ css «css» base directory
<mode.css.sprite> svg/sprite.css.svg Sprite location
<mode.css.render.css.dest> sprite.css CSS stylesheet location
<mode.css.render.scss.dest> sprite.scss Sass stylesheet location
...
<mode.view>/ view «view» base directory
...
By default, stylesheet resources are generated directly into the respective mode's base directory.
"Oh wait! Didn't you say that svg-sprite doesn't access the file system? So why do you need output directories at all?" — Well, good point. svg-sprite uses vinyl file objects to pass along virtual resources and to specify where they are intended to be located. This is especially important for relative file paths (e.g. the path of an SVG sprite as used by a CSS stylesheet).
Special care needs to be taken when you create a CSS sprite («css» or «view» mode) along with a stylesheet in one of the pre-processor formats (Sass, LESS, Stylus, etc.). In this case, calculating the correct relative SVG sprite path as used by the stylesheets can become tricky, as your (future) plain CSS compilation doesn't necessarily lie side by side with the pre-processor file. svg-sprite doesn't know anything about your pre-processor workflow, so it might have to estimate the location of the CSS file:
mode.<mode>.render.css.dest
as the CSS stylesheet location.mode.<mode>.render.css
to true
, the default value applies, which is mode.<mode>.dest / "sprite.css"
.mode.<mode>.dest / "sprite.css"
.So even if you don't enable plain CSS output explicitly, please make sure to set mode.<mode>.dest
to where your final CSS file is intended to be.
The complete configuration documentation including all options can be found here.
To get you quickly off the ground, I made a simple online configurator that lets you create a custom svg-sprite configuration in seconds. You may download the results as plain JSON, Node.js project, Gruntfile, or Gulpfile. Please visit the configurator at https://svg-sprite.github.io/svg-sprite/.
In order to improve accessibility, svg-sprite can read meta data from a YAML file and inject <title>
and <description>
elements into your SVGs. Please refer to the meta data injection guide for details.
For CSS sprites using a "horizontal"
or "vertical"
layout it is sometimes desirable to align the shapes within the sprite. With the help of an external YAML file, svg-sprite can not only control the alignment for each individual shape but also create displaced copies of them without significantly increasing the sprite's file size.
svg-sprite uses Mustache templates for rendering the various CSS resources. This makes it very easy to tailor the generated CSS / Sass / LESS / Stylus resources to your needs or add completely new output formats. Please refer to the templating guide to learn about the details.
svg-sprite comes with a pretty feature complete command line version. A typical example could look like this:
svg-sprite --css --css-render-css --css-example --dest=out assets/*.svg
Please refer to the CLI guide for further details.
<style>
or <script>
elements contained in the filePlease refer to the GitHub releases for a complete release history.
Copyright © 2018 Joschi Kuphal joschi@kuphal.net / @jkphl. svg-sprite is licensed under the terms of the MIT license. The contained example SVG icons are part of the Tango Icon Library and belong to the Public Domain.
FAQs
SVG sprites & stacks galore — A low-level Node.js module that takes a bunch of SVG files, optimizes them and bakes them into SVG sprites of several types along with suitable stylesheet resources (e.g. CSS, Sass, LESS, Stylus, etc.)
We found that svg-sprite demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.