svgsvg-pattern

Pattern no longer working when moving SVG to an external file


Here's an SVG. If you add this directly to your HTML page, it will render nicely. Note that the folder's right-hand side has a subtle shadow that's done with a black and white checker pattern.

<svg
        xmlns="http://www.w3.org/2000/svg"
        xmlns:xlink="http://www.w3.org/1999/xlink"
        version="1.1"
        width="96px"
        height="48px"
        viewBox="0 0 48 24"
        enable-background="new 0 0 48 24"
        id="svg"
    >
        <defs>
            <pattern id="checkers" x="0" y="0" width="2" height="2" patternUnits="userSpaceOnUse">
                <rect style="fill: #000" x="0" y="0" width="1" height="1"></rect>
                <rect style="fill: #000" x="1" y="1" width="1" height="1"></rect>
            </pattern>
        </defs>
        <path
            d="M 1 6 l 8 -4 l 37 0 v 12 l -5 8"
            style="fill: #fff; stroke: #000; stroke-width: 1px"
        />
        <path d="M 45.5 2 L 45.5 14 l -5 8" 
            style="fill: url(#checkers); stroke: none;"
        />
        <path 
            d="M 1 6 h 40 v 16 h -40 v -16" 
            style="fill: #fff; stroke: #000; stroke-width: 1px"
        />
        <path
            d="M 4 9 h 34 v 10 h -34 v -10"
            style="fill: transparent; stroke: #000; stroke-width: 1px"
        />
        <path
            d="M 17.5 13.5 l -1.5 1.5 l 8 0 l 1.5 -1.5 M 46 2 L 41 6" 
            style="fill: transparent; stroke: #000; stroke-width: 1px"
        />
    </svg>

I want to move this to an external file. I reference it from HTML like this:

<svg width="64px" height="64px">
    <use xlink:href="./svg/drawer.svg#svg" />
</svg>

However, when referenced like this, the SVG will render, but the pattern no longer works. The drawer's right-hand side is just white and does not show the checker pattern. I suspect url(#checkers) cannot be used within an external file. How do I do this instead?


Solution

  • I finally managed to get it working by using the object or img tag rather than svg with use. In HTML, I write:

    <object data="./svg/drawer.svg#svg" type="image/svg+xml"></object>
    

    Or:

    <img src="./svg/drawer.svg#svg" width="96px" height="48px"></img>
    

    The latter variant is probably better, because you can add an onClick handler to an img, but not to an object.

    I have no idea why this works and svg doesn't, so it would be good to know if someone the reason.