Search code examples
cssreactjsnode.jssvgsass

SASS is failing to compile SVGs as background images due to not recognising `%3C`. Is there a work around?


I'm compiling SASS in a Create-React-App project on a MacOS environment, with Node.js.

I'm running into an issue where my project fails to compile due to the UTF-8 characters %3C and %3E(representing < and >), eg in the CSS rule:

  background-image: url("data:image/svg+xml,%3Csvg...svg%3E");

Would anyone know if there's an alternative to using %3C and %3E when placing the SVG source code in a .scss file?

EDIT:

Error I'm getting in Storybook:

SassError: Undefined variable. node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[5].oneOf[7].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[5].oneOf[7].use[2]!./node_modules/resolve-url-loader/index.js??ruleSet[1].rules[5].oneOf[7].use[3]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[5].oneOf[7].use[4]!./src/styles/components/components.scss undefined

274 │background-image: url("data:image/svg+xml,%3Csvg width='464' height='243' xmlns='http://www.w3.org/2000/svg'%3E%3Cg #{$fill-stroke} fill-rule='evenodd'%3E%3Cpath d='M463.409 18.439l-.02 223.245L364.326 130.1l99.084-111.661zM231.847.5c10.354 0 20.063 4.372 26.808 12.006h0l104.333 117.516L263.256 242.5H1.112L205.216 12.505A35.488 35.488 0 01231.847.5z'/%3E%3C/g%3E%3C/svg%3E"); │
^^^^^^^^^^^^

src/styles/mixins/_svgs.scss 274:123 keyline()

The SCSS in question is a mixin (you could hard-code the variables to test):

@mixin keyline($color: 'green', $style: 'stroke') {
    $colorcode: colourcode($color);
    @if $style == fill {
        $fill-stroke: "fill='%23#{$colorcode}'";
    }
    @else {
       $fill-stroke: "fill='none' stroke='%23#{$colorcode}'";
    }
    background-image: url("data:image/svg+xml,%3Csvg width='464' height='243' xmlns='http://www.w3.org/2000/svg'%3E%3Cg #{$fill-stroke} fill-rule='evenodd'%3E%3Cpath d='M463.409 18.439l-.02 223.245L364.326 130.1l99.084-111.661zM231.847.5c10.354 0 20.063 4.372 26.808 12.006h0l104.333 117.516L263.256 242.5H1.112L205.216 12.505A35.488 35.488 0 01231.847.5z'/%3E%3C/g%3E%3C/svg%3E");
    background-repeat: no-repeat;
}

Solution

  • Note the SassError: Undefined variable part of the error: the SVG data-uri has ... #{$fill-stroke} ... in it, and the keyline mixin can't replace that $fill-stroke because by the time it tries to do so, that variable (no longer) exists.

    With the example above, change the mixin to:

    @mixin keyline($color: 'green', $style: 'stroke') {
        $colorcode: colourcode($color);
        $fill-stroke: "fill='none' stroke='%23#{$colorcode}'";
        @if $style == fill {
            $fill-stroke: "fill='%23#{$colorcode}'";
        }
        background-image: url("data:image/svg+xml,%3Csvg...#{$fill-stroke}...%3C/svg%3E");
        background-repeat: no-repeat;
    }