Git Product home page Git Product logo

gulp-svg-sprite's Introduction

svg-sprite

npm version Build Status Coverage Status npm downloads

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:

  • Traditional CSS sprites for use as background images,
  • CSS sprites with pre-defined <view> elements, useful for foreground images as well,
  • inline sprites using the <defs> element,
  • inline sprites using the <symbol> element
  • and SVG stacks.

It 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.

Grunt, Gulp & Co.

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.

Table of contents

Installation

To install svg-sprite globally, run:

npm install svg-sprite -g

Getting started

Crafting a sprite with svg-sprite typically follows these steps:

  1. You create an instance of the SVGSpriter, passing a main configuration object to the constructor.
  2. You register a couple of SVG source files for processing.
  3. You trigger the compilation process and receive the generated files (sprite, CSS, example documents etc.).

The procedure is the very same for all supported sprite types («modes»).

Usage pattern

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 of Object.values(result)) {
    for (const resource of Object.values(mode)) {
      fs.mkdirSync(path.dirname(resource.path), { recursive: true });
      fs.writeFileSync(resource.path, 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 of Object.values(result)) {
  for (const resource of Object.values(mode)) {
    fs.mkdirSync(path.dirname(resource.path), { recursive: true });
    fs.writeFileSync(resource.path, 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.

Configuration basics

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).

General configuration options

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.

Output modes

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
      // ...
    }
  }
}

Common mode properties

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
    }
  }
}

Basic examples

A) Standalone sprite

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
    }
  }
}
B) CSS sprite with Sass resource

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
      }
    }
  }
}
C) Multiple sprites

<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
  }
}
D) No sprite at all

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'
  }
}

Output destinations

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).

Pre-processor formats and the sprite location

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:

  1. If you truly configured CSS output in addition to the pre-processor format, svg-sprite uses your custom mode.<mode>.render.css.dest as the CSS stylesheet location.
  2. If you just enabled CSS output by setting mode.<mode>.render.css to true, the default value applies, which is mode.<mode>.dest / "sprite.css".
  3. The same holds true when you don't enable CSS output at all. svg-sprite then simply assumes that the CSS file will be created where the defaults would put it, which is again 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.

Full configuration documentation

The complete configuration documentation including all options can be found here.

Online configurator & project kickstarter

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/.

Advanced techniques

Meta data injection

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.

Aligning and duplicating shapes

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.

Tweaking and adding output formats

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.

Command line usage

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.

Known problems / To-do

  • SVGO does not minify element IDs when there are <style> or <script> elements contained in the file

Changelog

Please refer to the GitHub releases for a complete release history.

Legal

Copyright © 2018 Joschi Kuphal [email protected] / @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.

gulp-svg-sprite's People

Contributors

benfreke avatar danmindru avatar demurgos avatar dependabot[bot] avatar eagleeye avatar harveybanham avatar jkphl avatar jontorrado avatar kreeg avatar longzheng avatar mxmason avatar thedancingcode avatar tiagoporto avatar xhmikosr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gulp-svg-sprite's Issues

gulp-svg-sprite adds random characters to classes

Gulp-svg-sprite is adding random characters to the beginning of symbol group classes. It's not consistent either. The same "color1" class is used on a number of svg symbols, after svg-sprite has concatenated them the classes all have an extra two characters added to the start of the classname like so : "aacolor1", "adcolor1", "ahcolor1" etc. Seems very odd behaviour to me!

peerDependencies

npm WARN peerDependencies The peer dependency vinyl@^0.4.6 included from gulp-svg-sprite will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency 
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.

Preview Page

Thanks for creating this! Any chance of a preview page similar to how it was done in gulp-svg-sprites? We're building documentation pages and it'd be nice if we could reference the included/updated SVGs automatically. We've done something similar with IcoMoon's downloaded preview they give you, but really liked the way gulp-svg-sprites automatically created this for us. Thanks again!

Latest Node version on windows causes [Build Error] Skipping "%s" (%s) error

Hi!

Until this morning I had a perfectly fine working gulp-svg-sprite (v 1.2.19) task running with the following config:

{
    mode: {
        defs: {
            dest: '',
            sprite: 'service-icons.svg'
        }
    },
    svg: {
        xmlDeclaration: false,
        doctypeDeclaration: false
    }
}

And the following Gulp task:

gulp.task('service-icons', function () {  
    return gulp.src(config.src + 'images/service-icons/*')  
      .pipe(svgmin())  
      .pipe(svgsprite(config.svgConfig))  
      .pipe(gulp.dest(config.build + config.img.svg.path));  
});

This morning I've updated node.js to the latest version on Windows (via node-v4.3.1-x86.msi).
Since then I've got the following build error on the gulp-svg-sprite task.

Skipping "%s" (%s) error

Can't get it to work anymore, what I've tried/concluded this far:

  • my svg source files do not contain '%s'
  • disabling SVGO via transform: [] does not solve it
  • Adding { prefix: '' } to config > mode.defs does not solve it
  • disabling svgmin() does not solve it.
  • restarting pc after node install and updated dependencies

Any help, tips or tricks would be much appreciated, thanks in advance!

Cannot read property 'shapes' of undefined

Getting the following error with gulp-svg-sprite when trying to build (1.2.1):

[ERROR] <obscured>/workspace/node_modules/gulp-svg-sprite/index.js:63
[ERROR]         if (data.css.shapes.length > 0) {
[ERROR]                     ^
[ERROR] TypeError: Cannot read property 'shapes' of undefined
[ERROR]     at Array.<anonymous> (<obscured>/workspace/node_modules/gulp-svg-sprite/index.js:63:17)
[ERROR]     at <obscured>/workspace/node_modules/gulp-svg-sprite/node_modules/svg-sprite/lib/svg-sprite.js:256:11
[ERROR]     at <obscured>/workspace/node_modules/gulp-svg-sprite/node_modules/svg-sprite/lib/svg-sprite.js:298:3
[ERROR]     at <obscured>/workspace/node_modules/gulp-svg-sprite/node_modules/svg-sprite/node_modules/async/lib/async.js:678:13
[ERROR]     at <obscured>/workspace/node_modules/gulp-svg-sprite/node_modules/svg-sprite/node_modules/async/lib/async.js:49:16
[ERROR]     at replenish (<obscured>/workspace/node_modules/gulp-svg-sprite/node_modules/svg-sprite/node_modules/async/lib/async.js:304:29)
[ERROR]     at <obscured>/workspace/node_modules/gulp-svg-sprite/node_modules/svg-sprite/node_modules/async/lib/async.js:316:29
[ERROR]     at <obscured>/workspace/node_modules/gulp-svg-sprite/node_modules/svg-sprite/node_modules/async/lib/async.js:675:17
[ERROR]     at SVGSpriteSymbol.SVGSpriteBase._buildHTMLExample (<obscured>/workspace/node_modules/gulp-svg-sprite/node_modules/svg-sprite/lib/svg-sprite/mode/base.js:206:2)
[ERROR]     at SVGSpriteSymbol.<anonymous> (<obscured>/workspace/node_modules/gulp-svg-sprite/node_modules/svg-sprite/lib/svg-sprite/mode/standalone.js:119:9)

Any ideas?

Running tasks in series

Hello, thank for this plugin I use everyday,

My need: running tasks in series.

My problem:

  • Gulp-svg-sprite has "finish" status after SVG file creation => OK
  • If I want to generate SCSS (or CSS, or LESS) file, Gulp-svg-sprite has "finish" status before creation of file => NOT OK

I try with Gulp recipe Running task in series and with Run sequence.

gulp.task('svg:sprite', function() {
    gulp.src('path/to/assets/*.svg')
        .pipe(svgSprite( /* config */ ))
        .pipe(gulp.dest('out'));
});

gulp.task('svg:replace', function () {
    // modify SCSS output
});

gulp.task('svg:sass', function () {
    // compile SCSS
});

gulp.task('svg', function () {
    // svg:replace is running before svg:sprite update the SCSS file
    runSequence('svg:sprite', 'svg:replace', 'svg:sass');
});

Remove 'mode' name from output directory

Hey!

Trying to get set-up with this new package since 'gulp-svg-sprites' is no longer working. I have my SCSS and Sprite exporting but it's writing my directory structure inside of a 'view' folder on my site root. Is there a way to remove the 'mode' name folder and have the output SCSS and SVG files places in the directories I want?

For example:

What I am getting:

view > images > 'test.svg'
view > styles > scss > _partial > '_sprite.scss'

What I want:

images > 'test.svg'
styles > scss > _partial > '_sprite.scss'

I need these generated assets to go into the folders I have existing on my site otherwise I'm moving stuff around every time. How might I do this?

Thanks,
Brian

Issue with routes

Hi !

Im also struggeling with this issue. Im not able to archieve what I want. Sometimes, the files got generated properlly, and some other, they are not.

When seems that everything works nice. Im having problems with the url on the generated scss.

I want to generate svg sprites for two part of my app: public and admin. They have different structure.

So, lets have a look to my folder structure first.

|
|-> front-end // Here, I store all scss, gulp files, etc
|     |
|     |-> gulp
|     |     |
|     |     |-> tasks
|     |           |
|     |           |-> graphics
|     |           |     |
|     |           |     |-> svg-sprites.js // gulp task with gulp-svg-sprite
|     |           |
|     |           |-> config.js // config file for gulp
|     |
|     |-> m-scss // folder with my scss files
|     |     |
|     |     |-> admin
|     |           |
|     |           |-> sprites
|     |           |     |
|     |           |     |-> _admin-sprites.scss // Here is where I want to have outputted the svg sprite's scss regarding to admin
|     |           |
|     |           |-> sprites
|     |                 |
|     |                 |-> _sprites.scss // Here is where I want to have outputted the svg sprite's scss regarding to public area
|     |
|     |-> gulpfile.js
|
|
|-> web // public folder of the app
      |
      |-> admin-assets
      |     |
      |     |-> icons // Folder with all svg for admin area
      |     |
      |     |-> generated // Folder with the generated svg sprite for admin area
      |           |
      |           |-> admin-sprite.svg // Generated svg sprite for admin area
      |
      |-> m-img
            |
            |-> svgs // Folder with all svg for public area
            |
            |-> generated
                  |
                  |-> svg-sprites // Folder with the generated svg sprite for public area
                        |
                        |-> sprite.svg // Generated svg sprite for public area

This are my two tasks (on front-end/gulp/tasks/graphics/svg-sprites.svg );

gulp.task( 'svg-sprites', function () {
  return gulp.src( config.source )
    .pipe( changed( config.destination ) )
    .pipe( svgSprite( config.gulpSvgSpritesSettings ) )
    .pipe( gulp.dest( config.destination ) );
});

gulp.task( 'admin-svg-sprites', function () {
  return gulp.src( config.adminSource )
    .pipe( changed( config.adminSpritesDestination ) )
    .pipe( svgSprite( config.gulpSvgSpritesAdminSettings ) )
    .pipe( gulp.dest( config.adminSpritesDestination ) );
});

And these my (wrong) config file:

    config : {
        source : '../web/m-img/svgs/**/*.svg',
        destination : '../web/m-img/generated/svgs',
        gulpSvgSpritesSettings :
        {
            shape : 
            {
                spacing : 
                { 
                    padding : 5 
                }
            },
            mode : 
            {
                css : 
                {
                    dimensions : true,
                    common : 'svg-icon',
                    prefix : 'icon-',
                    bust : false,
                    sprite : '../sprite.svg',
                    render : 
                    {
                        scss    : 
                        { 
                            dest : '../../../../../front-end/m-scss/sprites/_sprites-svg.scss',
                        }
                    }
                }
            }
        },
        adminSource : '../web/admin-assets/icons/**/*.svg',
        adminSpritesDestination : '../web/admin-assets/generated',
        gulpSvgSpritesAdminSettings :
        {
            shape : 
            {
                spacing : 
                { 
                    padding : 5 
                }
            },
            mode : 
            {
                css : 
                {
                    dimensions : true,
                    common : 'svg-icon',
                    prefix : 'icon-',
                    bust : false,
                    sprite : '../../../../admin-assets/generated/admin-sprites.svg',
                    render : 
                    {
                        scss    : 
                        { 
                            dest : '../../../../front-end/m-scss/admin/sprites/_admin-sprites-svg.scss',
                        }
                    }
                }
            }
        },
    }

I really have a problem trying to understand how the routes works and how to archieve what Im looking for.

Any help will be very appreciated.

Thanks a lot !

dumb question alert

Does the svg sprite node module need to installed before this wrapper works?

I took the example config, changed the source directory to where my svgs are but there's no output, other than

%svg-common {
    background-repeat: no-repeat;
    background-image: url(svg/sprite.view.svg);
}

and 2 empty svg files.

Any ideas what I'm missing? Here's the gulpfile itself

var gulp = require('gulp');
var gulpif = require('gulp-if');
var sprite = require('css-sprite').stream;
var sass  = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var minifycss = require('gulp-minify-css');
var rename = require('gulp-rename');
var notify = require('gulp-notify');
var clean = require('gulp-clean');
var watch = require('gulp-watch');
var svgSprite = require('gulp-svg-sprite');
var plumber = require('gulp-plumber');
var path = require('path');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

// SVG sprite
config                  = {
    shape               : {
        dimension       : {         // Set maximum dimensions
            maxWidth    : 32,
            maxHeight   : 32
        },
        spacing         : {         // Add padding
            padding     : 10
        },
        dest            : 'out/intermediate-svg'    // Keep the intermediate files
    },
    mode                : {
        view            : {         // Activate the «view» mode
            bust        : false,
            render      : {
                scss    : true      // Activate Sass output (with default options)
            }
        },
        symbol          : true      // Activate the «symbol» mode
    }
};

gulp.task('svgsprite', function(){
  gulp.src('src/lib/svgsprite*.svg', {cwd: 'assets'})
    .pipe(svgSprite(config))
    .pipe(gulp.dest('out'));
});

Svg circle renders as square in Firefox (and occasionally in IE, Safari and Chrome too)

I've got a series of svg flag icons that have a <circle> applied to them, and exported with Illustrator. For a strange reason, the svg will randomly render as a square.

square-country-icon-bug

It's as-if Firefox has a mind of its own and renders the icon whichever way it chooses.

On another page, I use the same icons, and this is how they render in Firefox:

region-ff-bug

The same page in Internet Explorer (Edge), which somehow renders the outline of the icon, but doesn't render its internals:

region-ie-bug

On very rare occasions, I see similar behavior with Chrome, but for the most part, Chrome is rendering correctly.

HOWEVER, when I render each svg directly with an <img> tag (non-sprite), there are no issues in any browser. So not sure what it is about svg-sprite that is causing the problems.

Example svg:

<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<g>
    <defs>
        <circle id="SVGID_109_" cx="25" cy="25" r="25"/>
    </defs>
    <clipPath id="SVGID_110_">
        <use xlink:href="#SVGID_109_"  style="overflow:visible;"/>
    </clipPath>
    <g style="clip-path:url(#SVGID_110_);">
        <rect x="-1" style="fill:#FFFFFF;" width="52" height="50"/>
        <rect x="-1" style="fill:#BF0A30;" width="8.9" height="50"/>
        <path style="fill:#BF0A30;" d="M13.1,26.2l-1.4,0.5l6.4,5.6c0.5,1.4-0.2,1.9-0.6,2.6l6.9-0.9l-0.2,7h1.4l-0.1-7l6.9,0.8
            C32,33.9,31.6,33.4,32,32l6.4-5.3l-1.1-0.4c-0.9-0.7,0.4-3.4,0.6-5.1c0,0-3.7,1.3-4,0.6l-1-1.8l-3.4,3.7c-0.4,0.1-0.5-0.1-0.6-0.4
            l1.6-7.8L28,16.9c-0.2,0.1-0.4,0-0.6-0.2L25,11.9l-2.5,5c-0.2,0.2-0.4,0.2-0.5,0.1l-2.4-1.3l1.4,7.7c-0.1,0.3-0.4,0.4-0.7,0.2
            l-3.2-3.7c-0.4,0.7-0.7,1.8-1.3,2c-0.6,0.2-2.4-0.5-3.7-0.7C12.7,22.7,14,25.3,13.1,26.2L13.1,26.2z"/>
        <rect x="42.1" style="fill:#BF0A30;" width="8.7" height="50"/>
    </g>
</g>
<g>
    <path style="fill:#686868;" d="M25,50.025c-3.378,0-6.656-0.662-9.741-1.967c-2.98-1.261-5.656-3.065-7.955-5.363
        c-2.298-2.299-4.103-4.975-5.363-7.955C0.637,31.655-0.025,28.378-0.025,25c0-3.378,0.662-6.656,1.966-9.741
        c1.261-2.98,3.065-5.656,5.363-7.955s4.975-4.103,7.955-5.363C18.344,0.637,21.622-0.025,25-0.025c3.378,0,6.655,0.662,9.74,1.966
        c2.98,1.261,5.656,3.065,7.955,5.363c2.298,2.298,4.103,4.975,5.363,7.955c1.305,3.085,1.967,6.362,1.967,9.741
        c0,3.378-0.662,6.655-1.967,9.74c-1.261,2.98-3.065,5.656-5.363,7.955c-2.299,2.298-4.975,4.103-7.955,5.363
        C31.655,49.363,28.378,50.025,25,50.025z M25,0.025c-3.372,0-6.643,0.661-9.721,1.963C12.305,3.246,9.634,5.046,7.34,7.34
        c-2.293,2.294-4.094,4.965-5.352,7.939C0.686,18.357,0.025,21.628,0.025,25c0,3.371,0.661,6.643,1.963,9.721
        c1.258,2.975,3.059,5.646,5.352,7.939c2.294,2.293,4.965,4.094,7.939,5.353c3.079,1.302,6.35,1.962,9.721,1.962
        c3.371,0,6.643-0.66,9.721-1.962c2.975-1.259,5.646-3.06,7.939-5.353c2.293-2.294,4.094-4.965,5.353-7.939
        c1.302-3.078,1.962-6.35,1.962-9.721c0-3.372-0.66-6.643-1.962-9.721c-1.259-2.974-3.06-5.645-5.353-7.939
        c-2.294-2.293-4.965-4.094-7.939-5.352C31.643,0.686,28.371,0.025,25,0.025z"/>
</g>
</svg>

Dependency Suggestion

Hey Joschi,
Just noticed a npm suggestion they had when doing an update with your module:

The peer dependency vinyl@^0.4.6 included from gulp-svg-sprite will no longer be automatically installed to fulfill the peerDependency in npm 3+. Your application will need to depend on it explicitly.

Just a heads up for the future. Thanks again for making this package!

gulp svg sprite not generating

Hello,

I just setup a local project and was trying to get the gulp-svg-sprite plugin to work but i'm having some problems.

I have a gulpfile with a basic example taken from the homepage and it just doesn't do anything. The task itself starts and finishes but nothing gets generated.

If i use the original svg-sprite plugin and run the cli svg-sprite --css --css-render-css --dest=out *.svg it works fine and does what i expect but my gulp example - which is taken from the main page does nothing.

I've put my example on github, can someone care to look at this and explain what could be the problem?

How to deal with cc svg file ?

Hi @jkphl . i use the photoshop cc2015 to export some svg file from .psd file. the svg source code like this:

**the new.svg file**

<svg height="43" preserveAspectRatio="xMidYMid" viewBox="0 0 40 43" width="40" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <style>
      .cls-1 {
        fill: #33b6fa;
        fill-rule: evenodd;
      }
      .cls-2,
      .cls-3 {
        font-size: 22px;
      }
      .cls-3 {
        fill: #fff;
        font-family: &quot;
        STHeitiSC-Light&quot;
      }
    </style>
  </defs><path class="cls-1" d="M0 0h40v43l-20-5.292-20 5.292v-43z"/>
  <text class="cls-2" x="9" y="27">
    <tspan class="cls-3">新</tspan>
  </text>
</svg>

**the coin.svg file**

<svg height="36" preserveAspectRatio="xMidYMid" viewBox="0 0 36 36" width="36" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <style>
      .cls-1 {
        fill: #fff45c;
        stroke: #fc0;
        stroke-width: 2px;
      }
      .cls-2,
      .cls-3 {
        font-size: 20px;
      }
      .cls-3 {
        fill: #fc0;
        font-family: &quot;
        Microsoft YaHei&quot;
      }
    </style>
  </defs><circle class="cls-1" cx="18" cy="18" r="17"/>
  <text class="cls-2" x="8" y="24">
    <tspan class="cls-3">爽</tspan>
  </text>
</svg

now i want to use this gulp-plugin to bundle them to one svg-symbol file that i can use it on page by

<svg>
 <use xlink:href="svg-symbol.svg#coin"></use>
</svg>

my gulpfile config is

gulp.task('sprites', () =>{
  return gulp.src('img/icon/*.svg')
             .pipe($.svgSprite({
               mode: {
                 symbol: true
               }
             }))
             .pipe(gulp.dest('img'))
} )

and it generator the symbol file

<?xml version="1.0" encoding="utf-8"?>
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg">
  <symbol id="coin" preserveAspectRatio="xMidYMid" viewBox="0 0 36 36">
    <defs>
      <style>
        .acls-1 {
          fill: #fff45c;
          stroke: #fc0;
          stroke-width: 2px;
        }
        .cls-2,
        .cls-3 {
          font-size: 20px;
        }
        .acls-3 {
          fill: #fc0;
          font-family: "Microsoft YaHei";
        }
      </style>
    </defs><circle class="acls-1" cx="18" cy="18" r="17"/>
    <text class="acls-2" x="8" y="24">
      <tspan class="acls-3">爽</tspan>
    </text>
  </symbol>
  <symbol id="new" preserveAspectRatio="xMidYMid" viewBox="0 0 40 43">
    <defs>
      <style>
        .bcls-1 {
          fill: #33b6fa;
          fill-rule: evenodd;
        }
        .cls-2,
        .cls-3 {
          font-size: 22px;
        }
        .bcls-3 {
          fill: #fff;
          font-family: "STHeitiSC-Light";
        }
      </style>
    </defs><path class="bcls-1" d="M0 0h40v43l-20-5.292L0 43V0z"/>
    <text class="bcls-2" x="9" y="27">
      <tspan class="bcls-3">新</tspan>
    </text>
  </symbol>
</svg>

but i found i can't use it. can you tell me is there some solution to solve this case ? i will be very appreciate

Overriding background url in output LESS file

The LESS file currently created links to the the svg file in the same directory.
background: url(sprite.svg) no-repeat;
which is correct, but I have a subsequent gulp task that will create the combined .css file, which will no longer be in the same folder as the .svg.

What I want is
background: url(/special/deployment/path/sprite.svg) no-repeat;

Is there a way to specify that? Thank you.

Adobe Illustrator generated svg files are not getting sprited

Because of these attributes on the SVG element

xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;" 

when I try to run svg-sprite on files like this it fails with the following error

events.js:72
throw er; // Unhandled 'error' event

Error: Skipping "%s" (%s)

I guess the SAX parser in SVGO is not recognizing this as valid syntax. Any way to turn this strict mode off from gulp-svg-sprite?

My SVG file looks like this

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
    <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
    <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
    <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
    <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
    <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
    <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
    <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
    <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
]>
<svg version="1.1" id="Layer_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="51px" height="51px"
     viewBox="0 0 51 51" enable-background="new 0 0 51 51" xml:space="preserve">
<switch>
    <foreignObject requiredExtensions="&ns_ai;" x="0" y="0" width="1" height="1">
        <i:pgfRef  xlink:href="#adobe_illustrator_pgf">
        </i:pgfRef>
    </foreignObject>
    <g i:extraneous="self">
        <g>
            <g>
                <circle fill="#FFFFFF" cx="25.5" cy="25.5" r="25"/>
                <path fill="#D0D2D3" d="M25.5,51C11.4,51,0,39.6,0,25.5S11.4,0,25.5,0C39.6,0,51,11.4,51,25.5S39.6,51,25.5,51z M25.5,1
                    C12,1,1,12,1,25.5C1,39,12,50,25.5,50S50,39,50,25.5C50,12,39,1,25.5,1z"/>
            </g>
        </g>
        <g>
            <rect x="11.4" y="10" fill="#00A6A0" width="6.7" height="28"/>
            <rect x="28.1" y="17.8" fill="#00A6A0" width="6.7" height="20.2"/>
            <rect x="18.1" y="22.3" fill="#6E6F71" width="6.7" height="15.7"/>
            <rect x="34.8" y="27.9" fill="#6E6F71" width="6.7" height="10.1"/>
        </g>
    </g>
</switch>
<i:pgf  id="adobe_illustrator_pgf">
    <![CDATA[
    ... lot of data here ...
    ]]>
</i:pgf>
</svg>

output location of assets

So I'm probably not understanding the docs fully, so any help is appreciated.

I'm trying to output the generated .svg and .scss into standalone directories.

For example, I want the output .svg to go into the public/build/svg dir and the .scss to go into src/scss along with my other Sass partials before it gets built.

Should I be adding css-render-scss-dest after scss : true ?

config                  = {
    shape               : {
        dimension       : {         // Set maximum dimensions
            maxWidth    : 32,
            maxHeight   : 32
        },
        spacing         : {         // Add padding
            padding     : 10
        }
        dest            : 'public/build/svg'
    },
    mode                : {
        view            : {
            bust        : false,
            render      : {
                scss    : true
              }
        },
        symbol          : true      // Activate the «symbol» mode
    },
    example             : true
};

documentation suggestion

gulp.src('*/.svg', {cwd: 'assets'})

is misleading for a gulp beginner. I thought the cwd:'assets' part is some kind of configuration option. It took me a while to figure out, that that was the reason my images weren't found.
Also the, there is no output from gulp that indicates what it is doing. Hard locate mistakes.

Problem with svgId

The svgId property is not working as expected. I'm trying to add 'icon-' prefix to the id of every symbol in the sprite created by the gulpfile below but the symbols only have their file name as their IDs-


var gulp = require('gulp');
var svgSprite = require('gulp-svg-sprite');
var pages = ['home', 'offers', 'plays'];
gulp.task('sprite', function() {
  pages.forEach(function(page){
    gulp.src('svgs/'+page+'/*.svg')
    .pipe(svgSprite( 
      config = {
      mode : {
        symbol : {
          dest : '.',
          sprite : page+'/concatanated.svg',
        }
      },
      svgId : 'icon-%f'
    }
  ))
  .pipe(gulp.dest('svgs/build/'));
  })
});
gulp.task('default', ['sprite']);

Decapitated Bird

I have an SVG that is being mangled. The bird's head is effectively removed from its body and moved to new coordinates. In the CodePen example below you'll see the original SVG code followed by the output SVG code.

See: http://codepen.io/mcraiganthony/pen/KzEBaq

screen shot 2016-05-16 at 4 40 47 pm

I've had great success using gulp-svg-sprite with other, similar animations. It's saved me a TON of time. Here is an example: http://codepen.io/mcraiganthony/pen/XdPvmg

Any help would be appreciated. If you feel like this is the wrong forum for such a question, feel free to delete it. Thanks!

Prefix and Dimentions (suffix) Formatting

Hey jkphl,

Ok, now in the right repo. Sorry about that... For reference:

Tinkering with the SCSS output from this and having an issue with formatting for the output SCSS classes. Looking at the formatting for this: https://github.com/jkphl/svg-sprite#common-mode-properties

I'm updating the dimensions to have no value, but it actually seems to remove the Prefix as well (including the . for the class).

The Gulp.js Cofig

gulp.task( 'svg-sprite', function( ) {

    var config = {
        shape : {
            spacing : {
                padding : 5
            }
        },
        mode : {
            symbol : {
                bust : false,
                dest : '.',
                dimensions : '',
                layout : 'diagonal',
                prefix : '.icon-%s',
                render : {
                    scss: {
                        dest: 'css/scss/partial/_sprite.scss'
                    }
                },
                sprite : 'img/test.svg' //sprite-svg-ui.svg
            }
        }
    };

    gulp.src( 'img/svg/*.svg', { cwd: '' } )
        .pipe( plumber( { 'errorHandler': onError } ) )
        .pipe( imagemin( ) )
        .pipe( svgsprite( config ) )
        .pipe( gulp.dest( '' ) )
        .pipe( notify( { message: "'svg-sprite' completed" } ) );
} );

The Output in _sprite.scss:

 icon-feature-calculations {
    width: 66px;
    height: 59px;
}

There's a space at the start of it where my prefix should be.

Any thoughts?

Thanks,
Brian

Problem with hover to generate stylus

Hello @jkphl maybe I found another bug

I have 2 files

icon.svg
icon~hover.svg

My stylus generates

.svg-icon,
.svg-icon\\:regular
    background-position 0 50%
    @extend $svg-common

.svg-icon:hover,
.svg-icon\\:hover
    background-position 0 100%
    @extend $svg-common

.svg-icon-dims:hover,
.svg-icon\\:hover-dims
    width 104px
    height 104px

You can see these strange lines

.svg-icon\\:regular
.svg-icon\\:hover
.svg-icon\\:hover-dims

When the stylus is compiled, generates this

.svg-icon,
.svg-icon\:regular {
  background-position: 0 50%;
}
.svg-icon:hover,
.svg-icon\:hover {
  background-position: 0 100%;
}

.svg-icon-dims:hover,
.svg-icon\:hover-dims {
  width: 104px;
  height: 104px;
}

I'm on windows

Unexpected behavior because gulp-svg-sprite removes line-breaks...?

I'm wondering is there a config option to prevent gulp-svg-sprite from removing the line-breaks from the svg source. I have an svg with a really long <path> that runs several lines. But gulp-svg-sprite seems to be doing some sort of minification when it creates the sprite.

It takes an svg that looks like this:

motorcycle

original.svg:

<path style="fill:#58595B;" d="M18.052,3.858c-0.541,0-1.283,0.246-1.283,0.246c-0.13,0.043-0.294-0.019-0.362-0.138l-1.466-2.534
    c-0.069-0.119-0.021-0.173,0.106-0.12l0.366,0.153c0.127,0.053,0.343,0.096,0.481,0.096h0.259c0.138,0,0.25-0.113,0.25-0.25V0.25
    c0-0.137-0.112-0.25-0.25-0.25h-2.177c-0.137,0-0.362,0-0.5,0h-1.864c-0.137,0-0.25,0.113-0.25,0.25v0.259
    c0,0.137,0.113,0.25,0.25,0.25h1.714c0.137,0,0.306,0.097,0.375,0.217l0.214,0.371c0.069,0.119,0.012,0.217-0.125,0.217h-3.204
    c-0.137,0-0.25,0.112-0.25,0.25v1.07c0,0.138-0.113,0.25-0.25,0.25H9.742c-0.137,0-0.313-0.093-0.39-0.207L8.78,2.082
    C8.703,1.968,8.528,1.875,8.39,1.875h-5.7c-0.137,0-0.25,0.112-0.25,0.25v1.017c0,0.138,0.113,0.25,0.25,0.25h1.935
    c0.138,0,0.211,0.106,0.164,0.235L4.747,3.741C4.699,3.87,4.55,3.953,4.416,3.926c0,0-0.337-0.068-0.646-0.068
    C1.688,3.858,0,5.546,0,7.628c0,2.081,1.688,3.771,3.77,3.771c2.081,0,3.769-1.689,3.769-3.771c0-1.472-1.898-3.186-1.898-3.186
    C5.538,4.35,5.493,4.169,5.54,4.04l0.151-0.413C5.738,3.497,5.873,3.392,5.99,3.392s0.292,0.081,0.387,0.18
    c0,0,2.13,2.216,2.13,4.125c0,0.815-0.609,2.027-0.609,2.027c-0.062,0.123,0,0.223,0.138,0.223h4.673
    c0.137,0,0.274-0.11,0.304-0.244l1.331-6.067c0.029-0.134,0.166-0.244,0.304-0.244h0.196c0.137,0,0.306,0.097,0.375,0.216
    l0.459,0.795c0.069,0.119,0.052,0.302-0.038,0.406c0,0-1.358,1.585-1.358,2.819c0,2.081,1.688,3.771,3.769,3.771
    c2.082,0,3.77-1.689,3.77-3.771C21.822,5.546,20.134,3.858,18.052,3.858z"/>

...and because of the minification, causes it to render like this:

motorcycle2

sprite.svg:

<path d="M18.052 3.858c-.54 0-1.283.246-1.283.246a.32.32 0 0 1-.363-.138L14.94 1.432c-.068-.12-.02-.173.107-.12l.366.153c.127.053.343.096.48.096h.26a.25.25 0 0 0 .25-.25V.25a.25.25 0 0 0-.25-.25h-4.541a.25.25 0 0 0-.25.25v.26c0 .136.113.25.25.25h1.714a.48.48 0 0 1 .375.216l.215.37c.07.12.012.218-.125.218h-3.204a.25.25 0 0 0-.25.25v1.07a.25.25 0 0 1-.25.25h-.344a.53.53 0 0 1-.39-.207l-.572-.845a.527.527 0 0 0-.39-.207h-5.7a.25.25 0 0 0-.25.25v1.017c0 .138.113.25.25.25h1.935c.138 0 .21.106.164.235l-.043.114a.302.302 0 0 1-.33.186s-.338-.068-.647-.068a3.77 3.77 0 1 0 3.77 3.77c0-1.472-1.9-3.186-1.9-3.186a.4.4 0 0 1-.1-.402l.15-.413c.048-.13.183-.235.3-.235s.292.08.387.18c0 0 2.13 2.216 2.13 4.125 0 .815-.61 2.027-.61 2.027-.06.123 0 .223.14.223h4.672c.136 0 .273-.11.303-.244l1.33-6.067a.326.326 0 0 1 .305-.244h.196a.48.48 0 0 1 .375.216l.458.795c.07.12.052.302-.038.406 0 0-1.358 1.584-1.358 2.818a3.77 3.77 0 0 0 3.77 3.77 3.77 3.77 0 1 0 0-7.54z" fill="#58595b"/>

I manually pasted the original unminified path back into the right spot in the sprite, with all the original line-breaks, and it fixes the broken image (but of course that won't stay, because it rebuilds each time I run the build task).

Any ideas on what I could do in this case?

Install Problem

I cant install the package

npm WARN `git config --get remote.origin.url` returned wrong result (https://github.com/lodash/lodash)

And the installation doesnt end

Win 7 - 64bits

Empty SVG

Hello @jkphl

In my gulpfile.js, I use gulp-svg-sprite, but when the project is not necessary to work with any svg sprite is always generated an svg file empty.

How do I fix this?

Stylus path problem

Hello, i have the follow task in my gulpfile.js

gulp.task('svg-sprite', function() {
    gulp.src('src/images/svg-sprite/*.svg')
        .pipe(plumber())
        .pipe(svgSprite({
            mode : {
                css : {
                    dest : './',
                    sprite: '../images/svg-sprite.svg',
                    bust : false,
                    render : {
                        styl : {dest: '../../src/stylesheets/helpers/_svg-sprite.styl'}
                    }
                }
            }
        }))
        .pipe(gulp.dest('./public/images/'));
});

Works fine, the files are going to the right folders, and my .styl file generate this.

$svg-common 
    background-repeat no-repeat
    background-image url(..\images\svg-sprite.svg)

In the background-image the path is generated with backslash, when the stylus is compiled I have a problem, because they ignore the first backslash.

background-image: url("..imagessvg-sprite.svg");

Can someone help?

Invalid counter created files

If run the task without the svg files in a directory, the plugin will show an incorrect amount created files (but the files are not created).

SVG: 0
Created files: 1 SVG + 1 Less

image

Dead link on svg4everybody polyfill in examples

Hi, thank you for great tool. I found a dead link on polyfill svg4everybody in templates for symbol and defs examples. This link is not working now. You can use this CDN or another.

Ps. Also, you forget call the script.

<script>svg4everybody();</script>

Invalid mode configuration

My Code in Gruntfile.js

svg_sprite      : {
            your_target: {
                cwd: 'images/svg/fixture',
                src: ['*.svg'],
                dest: 'images/svg/expected',
                options     : {
                   shape               : {
                    dimension       : {         // Set maximum dimensions 
                        maxWidth    : 32,
                        maxHeight   : 32
                    },
                    spacing         : {         // Add padding 
                        padding     : 10
                    },
                    dest            : 'out/intermediate-svg'    // Keep the intermediate files 
                },
                }
            }
        },

grunt.registerTask("start", ["svg_sprite"]);
grunt.loadNpmTasks('grunt-svg-sprite');

using run command: grunt svg_sprite

Getting error:
Warning: SVG sprite compilation failed with message: ArgumentError: SVGSpriter.compile: "{}" is not a valid mode configu ration Use --force to continue.

PLEASE HELP ME TO FIX THIS ISSUE.

receiving class name without "."

I changed stylus template in order to receive another output:

{{#shapes}}
{{#selector.shape}}{{#escape}}{{expression}}{{/escape}}{{^last}},{{/last}}{{/selector.shape}}
  background-position {{position.relative.xy}}
  width {{width.outer}}px
  height {{height.outer}}px

{{/shapes}}

This outputs to stylus:

.svg-icon-1
  background-position 95.23809523809524% 45%
  width 10px
  height 10px

.svg-icon-2
  background-position 0 100%
  width 10px
  height 10px

My goal is to have such stylus output, where background-position, width and height are not set to css classes directly, but are kept in a separate variable, named the same as the file:

$svg-icon-1 = 95.23809523809524% 45% 10px 10px;
.svg-icon-1
  background-position $svg-icon-1[0]
  width $svg-icon-1[1]
  height $svg-icon-1[2]

$svg-icon-2 = 0 100% 10px 10px;
.svg-icon-2
  background-position $svg-icon-2[0]
  width $svg-icon-2[1]
  height $svg-icon-2[2]

In order to get that stylus output I changed the template file:

{{#shapes}}
${{#selector.shape}}{{#escape}}{{expression}}{{/escape}}{{^last}},{{/last}}{{/selector.shape}} = {{position.relative.xy}} {{width.outer}}px {{height.outer}}px;
{{#selector.shape}}{{#escape}}{{expression}}{{/escape}}{{^last}},{{/last}}{{/selector.shape}}
  background-position {{#selector.shape}}{{#escape}}{{expression}}{{/escape}}{{^last}},{{/last}}{{/selector.shape}}[0]
  width {{#selector.shape}}{{#escape}}{{expression}}{{/escape}}{{^last}},{{/last}}{{/selector.shape}}[1]
  height {{#selector.shape}}{{#escape}}{{expression}}{{/escape}}{{^last}},{{/last}}{{/selector.shape}}[2]

{{/shapes}}

where the code below should produce the variable containing $ and the name of .svg file, containing background-position at [0], width at [1] and height at [2]

${{#selector.shape}}{{#escape}}{{expression}}{{/escape}}{{^last}},{{/last}}{{/selector.shape}} = {{position.relative.xy}} {{width.outer}}px {{height.outer}}px;

The issue is that this part of code:

{{#selector.shape}}{{#escape}}{{expression}}{{/escape}}{{^last}},{{/last}}{{/selector.shape}}

produces the css class, containing the "." + "filename", with my template resulting in:

$.svg-icon-2

that is compiled by stylus not as a variable, but as a property (everything started with a dot is assumed to be a property).

How can I get the pure filename without a dot at the beggining, not a css class? Is it possible? In gulp.spritesmith it is possible by simply using {{strings.name}} in template, what gives a user much more control and possibilities to get the needed output.

I assume that the name of the file is this - {{expression}} , but it doesn't output anything if is used out of {{#selector.shape}}{{/selector.shape}}

Doesn't appear to work with gulp changed in the way other gulp plugins do?

In order to have the defs generation only happen when there's an update or addition to the separate svg icons I am running the svg sprite task first - parsing in the icons from the source and writing to the defs dest. The task that publishes the icons to the dest folder only runs when there's a change in the icon directory but the svg sprite task runs every single time so looks to me like it's not working with the gulp changed pipe in the way other gulp plugins do? Am I missing something?

gulp.task('publish_SVG', ['publish_svg_defs'], function () {

  return gulp.src(config.svg_icons.src)
             .pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
             .pipe(gulpif(is_debug, debug({ verbose: true })))
             .pipe(changed(config.svg_icons.dest))
             .pipe(gulp.dest(config.svg_icons.dest))
             .pipe(notify('Published SVG'));
});


gulp.task('publish_svg_defs', function () {

  var svg_defs_config = {
    svg: {
      namespaceIDs: false
    },
    log: 'verbose',
    mode: {
      defs:{
        dest: './',
        inline: true,
        sprite: config.svg_defs.sprite_file_name
      }
    }
  }

  return gulp.src(config.svg_icons.src)
             .pipe(plumber({errorHandler: notify.onError('Error: <%= error.message %>')}))
             .pipe(gulpif(is_debug, debug({ verbose: false })))
             .pipe(changed(config.svg_icons.dest))
             .pipe(svgSprite(svg_defs_config))
             .pipe(gulp.dest(config.svg_defs.dest))
             .pipe(notify('Published SVG icons into sprite.svg.defs file'));
});

Generated paths in scss file are wrong when using custom template

I am using a mustache template to generate a sass map using the svg sprite task. This works fine apart from the fact that the paths are not generated properly in the scss file. At first I just used hardcoded links to the sprite but now I want to use cache busting and can't do that anymore.

My template looks as follows:

$icons: (
    sprite: (width: {{spriteWidth}}px, height: {{spriteHeight}}px, pngPath: '../img/sprite.png', svgPath: '../{{sprite}}'),
{{#shapes}}     {{base}}: (width: {{width.inner}}px, height: {{height.inner}}px, backgroundX: {{position.absolute.x}}px, backgroundY: {{position.absolute.y}}px),
{{/shapes}});

Now the part that goes wrong is svgPath. This will generate:

svgPath: '../img&#x2F;sprite.svg'

So it seems its replacing the forward slash with the hex code for a forward slash.
Any idea how to fix this? Or work around it?

SVG ID# Names

Is there a specific setting I need to use to allow ID names to display in my SVG files when processing them through gulp-svn-sprite? The reason I ask is because when I export my SVG out of illustrator I can see the ID names in the exported code. I guess the goal is to get the ID names to display on the paths. See below example from Illustrator:

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 16"><title>eyepreso</title><g id="eye"><path id="outer" d="M12,4C4.1,4,0,12,0,12s3.1,8,12,8c8.1,0,12-8,12-8S20.1,4,12,4Zm0,13a4.89,4.89,0,0,1-5-5,4.89,4.89,0,0,1,5-5,4.89,4.89,0,0,1,5,5A4.89,4.89,0,0,1,12,17Z" transform="translate(0 -4)"/></g><g id="inner"><path id="inner-2" data-name="inner" d="M12,9a3,3,0,1,0,3,3A3,3,0,0,0,12,9Z" transform="translate(0 -4)"/></g></svg>

However when I run my gulp task I'm not seeing the ID name on the paths: Here is what is displayed:

<symbol viewBox="0 0 24.02 16" id="eyepreso"><title>eyepreso2</title><path data-name="outer" d="M12.01 0c-7.94 0-12 8-12 8s3.07 8 12 8c8.09 0 12-8 12-8s-3.94-8-12-8zm0 13a4.88 4.88 0 0 1-5-5 4.88 4.88 0 0 1 5-5 4.88 4.88 0 0 1 5 5 4.88 4.88 0 0 1-5 5z"></path><path data-name="inner" d="M12.01 5a3 3 0 1 0 3 3 3 3 0 0 0-3-3z"></path></symbol>

Below is my gulp task:
`// Basic configuration example for SVG Sprite
var config = {
shape : {
dimension : { // Set maximum dimensions
maxWidth : 32, // Max. shape width
maxHeight : 32, // Max. shape width
precision : 2, // Floating point precision
attributes : true, // 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`)
    },
    dest            : 'intermediate-svg'    // Keep the intermediate files
},
svg                     : {                           // General options for created SVG files
    xmlDeclaration      : false,                     // Add XML declaration to SVG sprite
    doctypeDeclaration  : false,                    // Add DOCTYPE declaration to SVG sprite
    namespaceIDs        : true,                    // Add namespace token to all IDs in SVG shapes
    dimensionAttributes : true,                   // Width and height attributes on the sprite
    rootAttributes: {
        width: 0,
        height: 0,
        style: 'position:absolute; background:none !important'
    },
},
mode                : {
    view            : {         // Activate the «view» mode
        bust        : false,
        render      : {
            scss    : true      // Activate Sass output (with default options)
        }
    },
    css             : {
        example     : true
    },
    inline          : true,
    symbol          : true     // Activate the «symbol» mode
}

};

// Build SVG sprites and move to build folder
gulp.task('svgSprite', function() {
return gulp.src('assets/svg/*.svg')
.pipe(svgSprite(config))
.pipe(gulp.dest('assets/build/svg'))
.pipe(notify({ message: 'SVG task complete'}));
});

// Images: Removes images not in src folder
gulp.task('cleanSVG', function(){
del(['assets/build/svg//*', '!assets/svg', '!assets/svg//*'])
});`

Gradients don't make it into the external file

I happened to have quite a few icons with linear gradients in them (like this one), and when I inline all my icons into an external file with <symbol>s, the gradient gets lost. Interestingly enough, the code for gradients still remains in the external minified file, although it doesn't appear in the browser:

screenshot 2016-01-22 15 57 52

My Gulp task:

gulp.task('svg', function () {
    gulp.src('./assets/img/svgs/**/*.svg')
        .pipe(svgSprite({
            mode: {
                symbol: true
            }
        }))
        .pipe(rename('icons.svg'))
        .pipe(gulp.dest('./assets/img/'));
});

Has anyone of you ever encounter something like this?

Plugin don't work on Gulp 4

Does gulp-svg-sprite work with new Gulp version?
Now running plugin with any options gives such error:

[12:40:50] Error in plugin 'gulp-svg-sprite'
Message:
    Skipping "%s" (%s)
Details:
    domainEmitter: [object Object]
    domain: [object Object]
    domainThrown: false

I suppose this is due to deprecated status of gulp-util package.

"{}" is not a valid mode configuration

I tried to replace the old gulp-svg-sprites with you gulp-svg-sprite package, and I'm running into the following error:

events.js:72
        throw er; // Unhandled 'error' event
              ^
ArgumentError: SVGSpriter.compile: "{}" is not a valid mode configuration

And my gulp task:

gulp.task('icons', [], function(){
    var env = util.env();

    return gulp.src(config.icons.src.files)
        .pipe($.plumber({ errorHandler: util.error }))
        // Create SVG Sprite
        .pipe( $.svgSprite({ mode: { symbols: true } }) )
        .pipe( $.gulpif( env.name === env.types.DIST,
            $.gzip({ append: false }),
            $.gutil.noop())
        )
        .pipe( gulp.dest(config.icons[env.name].path) );
});

The configuration is clearly there. Any idea what could be causing this?

Solution for PNG-fallback

Is there currently a solution for using/configuring a PNG-fallback? It's easy to create PNG images using the gulp-raster plugin but the more difficult part is to get the additional styles into the CSS/SASS file.

I've seen it's possible to use custom templates for rendering stylesheet files in the documentation of svg-sprite, but it's not mentioned anywhere how to configure them.

Thanks!

How to specify an scss template

Hey,

how can I specify the scss template to be used? And can I also configure the destination for the generated scss file or should I just move afterwards?

Thanks in advance,
Robert

Is it possible to add 'style="display:none"' to svg?

Currently, the output for the svg sprite in symbol mode does not provide any styling. When file is included in the HTML , a big blank space is rendered on top of the page by the browser.

This is normal behaviour with svg sprites when no styling is added. So could 'style="display:none"' be added to the svg tag of the file? Adding it manually fixes the issue, but it has to be done every time the sprite is generated

Not sure if it's an svg-sprite issue, so my apologies in advance if it is

Example in readme not working.

Hi!

Your example in the readme:

var gulp                = require('gulp'),
svgSprite               = require('gulp-svg-sprite');

gulp.src('assets/*.svg')
    .pipe(svgSprite())
    .pipe(gulp.dest('out'));

does not actually send any files down stream I had a quick skim through the re-written svg-sprite module and I think you'll need to specify a default config that can be extended in this gulp plugin.

If I do

gulp.src('assets/*.svg')
    .pipe(svgSprite({
        mode                : {
            css             : {     // Activate the «css» mode
                render      : {
                    css     : true  // Activate CSS output (with default options)
                }
            }
        }
    }))
    .pipe(gulp.dest('out'));

then everything works as expected :)

SVG Export and CSS Formatting

Hello, I'm currently the gulp structure below (also attached) for my SVG icon system and have it exporting out to a php file to include in the head of Wordpress so I can use SVG's on the page.

For the most part everything works great however when I try to apply a hover: class to change the SVG fill, I'm not able to change the fill. I can change the fill if I use but not on hover. I assuming it's because of the path after the #ID.

Is there a better way I should be exporting my SVG or have my GULP file setup? The goal is to use symbol for my SVG's.

CSS

svg #pin path {
    fill:deepskyblue;
}

PHP

<div><svg><use xlink:href="#pin"/></use></svg></div>

Gulp

// SVG:
// Basic configuration example for SVG Sprite
var config                  = {
    shape               : {
        dimension       : {              
            maxWidth    : 32,           
            maxHeight   : 32,       
            precision   : 2,           
            attributes  : true,     
        },
        spacing         : {       
            padding     : 0,         
            box         : 'content'  
        },
        dest            : 'intermediate-svg'    
    },
    svg                     : {                          
        xmlDeclaration      : false,                     
        doctypeDeclaration  : false,                    
        namespaceIDs        : true,                    
        dimensionAttributes : true,                  
        rootAttributes: {
            width: 0,
            height: 0,
            style: 'position:absolute; background:none !important'
        },
    },
    mode                : {
        view            : {        
            bust        : false,
            render      : {
                scss    : true      
            }
        },
        css             : {
            example     : true
        },
        inline              : true,
        symbol          : true    
    }
};

// Build SVG sprites and move to build folder
gulp.task('svgSprite', function() {
    return gulp.src('assets/svg/*.svg')
        .pipe(svgSprite(config))
        .pipe(gulp.dest('assets/build/svg'))
        .pipe(notify({ message: 'SVG task complete'}));
});

// Images: Removes images not in src folder
gulp.task('cleanSVG', function(){
  del(['assets/build/svg/**/*', '!assets/svg', '!assets/svg/**/*'])
});


// Rename and create symbols php file
gulp.task('rename', function() {
    return gulp.src('assets/build/svg/symbol/svg/*.svg')
        .pipe(rename({
            basename: "svg",
            suffix: "-symbols",
            extname: '.php'
    }))
    .pipe(gulp.dest('parts'))
    .pipe(browserSync.stream())
    .pipe(notify({ message: 'Rename task complete'}))
});

Gulp-SVG.txt

Don't include XML prologue, DOCTYPE, etc. in generated SVG sprite file when using inline symbol mode

In my project, I'm using the following gulp task:

gulp.task('svg-icons', function() {
  return gulp
    .src("./src/icons/**/*.svg")
    .pipe(plumber(handleError))
    .pipe(svgSprite({
      mode: {
        symbol: {
          inline: true,
          example: true
        }
      }
    }))
    .pipe(gulp.dest('./dist'));
});

Running it creates the following file structure:

dist/
  symbol/
    svg/
      sprite.symbol.svg
    sprite.symbol.html

My expectation is that since I've set mode.symbol.inline in my config object to true, the file sprite.symbol.svg would only consist of the <svg> element and any nested elements/content (i.e., not the XML namespace declaration, DOCTYPE, etc.). In another step of my build process, I'm including the full output of sprite.symbol.svg in my main HTML file, so only the <svg> element and its contents are needed there (otherwise I'll need to strip them somehow).

Does this seem like a bug, or am I not understanding (or using) the inline option correctly?

Great work here, BTW!

Type Error: Cannot read property 'length' of undefined

I was trying out the library and it outputs this error on this task.

gulp.task('svgs', function() {
    gulp.src('svgs/*.svg')
        .pipe($.svgo())
        .pipe($.svgSprites({
            "mode": {
                "css": {
          "render": {
            "css": true
          }
                }
            }
        }))
        .pipe(gulp.dest('svgs'))
});

And the error log is here:

/Users/chrisyeung/cmd/playground/gulp/node_modules/gulp-svg-sprites/node_modules/svg-sprite-data/node_modules/css-selector-parser/lib/css-selector-parser.js:172
      l = str.length;
             ^
TypeError: Cannot read property 'length' of undefined
    at new exports.CssSelectorParser.ParseContext (/Users/chrisyeung/cmd/playground/gulp/node_modules/gulp-svg-sprites/node_modules/svg-sprite-data/node_modules/css-selector-parser/lib/css-selector-parser.js:172:14)
    at CssSelectorParser.exports.CssSelectorParser.CssSelectorParser.parse (/Users/chrisyeung/cmd/playground/gulp/node_modules/gulp-svg-sprites/node_modules/svg-sprite-data/node_modules/css-selector-parser/lib/css-selector-parser.js:474:17)
    at SVGObj.<anonymous> (/Users/chrisyeung/cmd/playground/gulp/node_modules/gulp-svg-sprites/node_modules/svg-sprite-data/lib/svg-obj.js:238:21)
    at Array.forEach (native)
    at SVGObj._replaceIDReferences (/Users/chrisyeung/cmd/playground/gulp/node_modules/gulp-svg-sprites/node_modules/svg-sprite-data/lib/svg-obj.js:235:9)
    at SVGObj.<anonymous> (/Users/chrisyeung/cmd/playground/gulp/node_modules/gulp-svg-sprites/node_modules/svg-sprite-data/lib/svg-obj.js:192:19)
    at Array.forEach (native)
    at SVGObj.namespaceIDs (/Users/chrisyeung/cmd/playground/gulp/node_modules/gulp-svg-sprites/node_modules/svg-sprite-data/lib/svg-obj.js:191:68)
    at /Users/chrisyeung/cmd/playground/gulp/node_modules/gulp-svg-sprites/node_modules/svg-sprite-data/lib/svg-sprite.js:395:21
    at fn (/Users/chrisyeung/cmd/playground/gulp/node_modules/gulp-svg-sprites/node_modules/svg-sprite-data/node_modules/async/lib/async.js:582:34)
    at Object._onImmediate (/Users/chrisyeung/cmd/playground/gulp/node_modules/gulp-svg-sprites/node_modules/svg-sprite-data/node_modules/async/lib/async.js:498:34)
    at processImmediate [as _immediateCallback] (timers.js:330:15)

SVG dimensionAttributes boolean not being respected

When SVG dimensionAttributes boolean is set to false the generated sprite still has height and width attributes on the symbols.

xmlDeclaration and doctypeDeclaration work as expected.

I reverted to 1.2.19 to verify.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.