I’ve been dealing with this issue today as well. It looks like SVGO is the culprit, it runs as part of cssnano and ImageminPlugin and breaks SVGs placed as background-images with a data:uri in (S)CSS.
As an example:
background-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><defs><pattern id="pinstripe" patternUnits="userSpaceOnUse" width="8" height="8" patternTransform="rotate(-45)"><line x1="4" y="0" x2="4" y2="8" stroke="#{$brand-primary}" stroke-width="2" /></pattern></defs><rect width="100%" height="100%" fill="url(#pinstripe)" /></svg>');
Probably one of the default SVGO plugins is interfering, as I have had the problem with my SVG sprites as well (breaking them or causing display issues).
I’ve looked into the default SVGO plugin set and tried to disable them one by one, but in the end decided to disable SVGO all together, this makes both my sprites and inline SVG work again, but you miss out on any optimisations.
My webpack.config.optimize.js looks like this to make SVG sprites behave as expected:
'use strict'; // eslint-disable-line
const { default: ImageminPlugin } = require('imagemin-webpack-plugin');
const imageminMozjpeg = require('imagemin-mozjpeg');
const config = require('./config');
module.exports = {
plugins: [
new ImageminPlugin({
optipng: { optimizationLevel: 7 },
gifsicle: { optimizationLevel: 3 },
pngquant: { quality: '65-90', speed: 4 },
svgo: null,
plugins: [imageminMozjpeg({ quality: 75 })],
disable: (config.enabled.watcher),
}),
],
};
And postcss.config.js to avoid the stripping of inline SVGs in (S)CSS:
/* eslint-disable */
const cssnanoConfig = {
preset: ['default', { discardComments: { removeAll: true }, svgo: false }]
};
module.exports = ({ file, options }) => {
return {
parser: options.enabled.optimize ? 'postcss-safe-parser' : undefined,
plugins: {
cssnano: options.enabled.optimize ? cssnanoConfig : false,
autoprefixer: true,
},
};
};