csssvgbackgroundspritesvg-sprite

How can i make an SVG-sprite tile properly in a CSS background?


I'm trying to use part of an SVG as a tiling background. However I'm having great problems making it work properly.

I think a picture will illustrate the problem best: demonstration picture

This is my CSS:

body {
background: url("tiletest.svg#svgView(viewBox(120 32 150 64))");
background-size: 30px 32px;
}

And here is the code of the SVG I'm using for the demonstration:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg height="100" width="360" version="1.1" id="Lager_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 360 100" style="enable-background:new 0 0 360 100;" xml:space="preserve">
<style type="text/css">
.st0{fill:url(#SVGID_1_);}
    .st1{fill:#13FF00;}
    .st2{fill:#2732FF;}
</style>
<g>
    <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="9.094947e-13" y1="9.094947e-13" x2="100" y2="100">
        <stop  offset="0" style="stop-color:#E7FF00"/>
        <stop  offset="1" style="stop-color:#FF0000"/>
    </linearGradient>
    <rect class="st0" width="100" height="100"/>
</g>
<polygon class="st1" points="174.68,0 190.92,32.92 227.25,38.2 200.96,63.82 207.17,100 174.68,82.92 142.19,100 148.39,63.82 
    122.11,38.2 158.43,32.92 "/>
<circle class="st2" cx="310" cy="50" r="50"/>
</svg>

As you can see the full viewbox in the SVG is 0 0 360 100 and when I call the SVG in the CSS I'm giving it a new viewbox of 120 32 150 64, as well as changing the background size accordingly (though I'm pretty sure this shouldn't matter anyway as the svg defined by the viewbox is supposed to expand to fill the container no matter size,right?).

I've tried fiddling with the viewbox in the SVG, with the width and height, with the preserveAspectRatio attribute, and so far nothing has worked. What am I doing wrong?


Solution

  • <update>

    While what I wrote below is useful it did not fully fix your problem. With the proviso that Safari and iOs support is flakey, I got your code working by removing the height and width on the SVG as below:

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 100">
      <linearGradient id="grad" x2="100" y2="100" gradientUnits="userSpaceOnUse">
        <stop offset="0" stop-color="#E7FF00"/>
        <stop offset="1" stop-color="#F00"/>
      </linearGradient>
      <path d="M0 0h100v100H0z" fill="url(#grad)"/>
      <path d="M174.68 0l16.24 32.92 36.33 5.28-26.29 25.62 6.21 36.18-32.49-17.08L142.19 100l6.2-36.18-26.28-25.62 36.32-5.28z" fill="#13FF00"/>
      <circle cx="310" cy="50" r="50" fill="#2732FF"/>
    </svg>
    

    Using following html worked in Chrome, Firefox and IE11:

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>SVG Fragment</title>
      <style type="text/css">
      body {
        background: url("tiletest.svg#svgView(viewBox(120,32,30,32))");
        background-size: 30px 32px;
      }
      </style>
    </head>
    <body>
      <h1>SVG Fragment</h1>
    </body>
    </html>
    

    </update>

    A couple of things, support for inline viewbox is not there in all browsers yet ... and often has quirks (see links at bottom) ... the other is that the viewbox is x-min y-min width height ... you appear to have thought it is x1 y1 x2 y2.

    You should have used background: url("tiletest.svg#svgView(viewBox(120 32 30 32))"); for it to work in Chrome ... though you may need to use a view element to get it working in Firefox.

    I've shown another way to implement what you want below which will work in all modern browsers (except Opera Mini and a few others). Hope it gives you some ideas.

    .svg-background {
      height: 200px;
      background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='120 32 30 32'%3E%3ClinearGradient id='grad' x2='100' y2='100' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0' stop-color='%23E7FF00'/%3E%3Cstop offset='1' stop-color='%23F00'/%3E%3C/linearGradient%3E%3Cpath d='M0 0h100v100H0z' fill='url(%23grad)'/%3E%3Cpath d='M174.68 0l16.24 32.92 36.33 5.28-26.29 25.62 6.21 36.18-32.49-17.08L142.19 100l6.2-36.18-26.28-25.62 36.32-5.28z' fill='%2313FF00'/%3E%3Ccircle cx='310' cy='50' r='50' fill='%232732FF'/%3E%3C/svg%3E");
    }
    <svg xmlns="http://www.w3.org/2000/svg" width="100" viewBox="0 0 360 100">
      <linearGradient id="grad" x2="100" y2="100" gradientUnits="userSpaceOnUse">
        <stop offset="0" stop-color="#E7FF00"/>
        <stop offset="1" stop-color="#F00"/>
      </linearGradient>
      <path d="M0 0h100v100H0z" fill="url(#grad)"/>
      <path d="M174.68 0l16.24 32.92 36.33 5.28-26.29 25.62 6.21 36.18-32.49-17.08L142.19 100l6.2-36.18-26.28-25.62 36.32-5.28z" fill="#13FF00"/>
      <circle cx="310" cy="50" r="50" fill="#2732FF"/>
    </svg>
    
    <div class="svg-background">
      
    </div>

    Further Reading: