gulp-stacksvg v3.0.0
gulp-stacksvg
The gulp plugin to combine svg files into one using the stack method.
Installation
npm install gulp-stacksvg --save-dev
Usage
The following script will combine all SVG sources into a single SVG file with stack method.
import { stacksvg } from "gulp-stacksvg"
import gulp from "gulp"
const { src, dest } = gulp
function makeStack () {
return src(`./src/icons/**/*.svg`)
.pipe(stacksvg({ output: `sprite` }))
.pipe(dest(`./dest/icons`))
}
Available options
Option | Description | Default |
---|---|---|
output | Sets the stack file name. Accepts values both with and without the .svg extension. | stack |
separator | Replaces the directory separator for the id attribute. | _ |
spacer | Joins space-separated words for the id attribute. | - |
Inlining stacksvg result into markup
You just don't have to want it.
Why a stack?
Unlike all other methods for assembling a sprite, the stack does not limit us in choosing how to insert a vector into a page. Take a look at the results of different ways to display fragments of different types of sprites.
We can use the stack in all four possible ways:
in markup:
- in `src` of `img` tag — static, - in the `href` of the `use` tag — with the possibility of repainting,
in styles:
- in `url()` properties `background` — static, - in `url()` properties `mask` — with the possibility of repainting.
Demo page to prove it.
Stack under the hood
This method was first mentioned in a Simurai article on April 2, 2012. But even it uses unnecessarily complex code transformations.
This can be done much easier. In general, the stack is arranged almost like a symbol sprite, but without changing the icon tag (it remains the svg
tag, as in the original icon files) and with the addition of a tiny bit of style.
<svg xmlns="http://www.w3.org/2000/svg">
<style>:root svg:not(:target) { display: none }</style>
<svg id="sun" viewBox="0 0 24 24">
<!-- Inner code of sun icon -->
</svg>
<svg id="heart" viewBox="0 0 24 24">
<!-- Inner code of heart icon -->
</svg>
<svg id="thumbup" viewBox="0 0 24 24">
<!-- Inner code of thumbup icon -->
</svg>
</svg>
The magic is in the stack inner style, which shows only the fragment requested by the link, hiding everything else:
:root svg:not(:target) { display: none }
And now the icons from the external sprite are available in the styles
<button class="button button--icon_heart" type="button">
<span class="visually-hidden">Add to favorites</span>
</button>
.button {
display: inline-flex;
align-items: center;
gap: 0.5em;
}
.button--icon_heart {
--icon: url("../icons/stack.svg#heart");
}
.button:hover {
--fill: red;
}
.button::before {
content: "";
width: 1em;
height: 1em;
/* icon shape */
mask: var(--icon) no-repeat center / contain;
/* icon color */
background: var(--fill, orangered);
}
⚠️ Note: We still need the autoprefixer for the mask property.
For an icon inserted via mask
, simply change the background
. Moreover, unlike use
, you can draw anything in the background under the mask, for example, a gradient.