TelFiRE
TelFiRE

Reputation: 472

SVG as a CSS Background - Is there ANY way to repeat-x with NO space in between?

In Webkit and Blink-based browsers, SVGs do not tile correctly. There is a space between the images at various zoom levels. There are a number of topics on StackOverflow addressing this, all marked as solved, but those people must not have tested their solutions thoroughly enough.

My SVGs are a perfectly even number of pixels (130 x 24). They have background-size set to 130px 24px. They are set to preserveAspectRatio="none". There is absolutely zero empty space on the edges of the SVG.

Yet, while it looks fine at 100%, there is still a thin space between the SVGs if you zoom in to the right level.

It surprises me this bug has not been reported before, given the widespread recommendations of using SVGs for backgrounds.

Here is the exact SVG:

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
    	 viewBox="0 0 130 24" xml:space="preserve" preserveAspectRatio="none">
    <style type="text/css">
    	.st0{fill:#A5EF8B;}
    </style>
    <path class="st0" d="M0,12c32.5,0,32.5,12,65,12s32.5-12,65-12V0C97.5,0,92.9,12,65,12C32.5,12,20.7,0,0,0"/>
    </svg>

I can confirm this behavior with other SVGs as well, such as the ones at https://www.heropatterns.com/

Codepen for testing: https://codepen.io/TelFiRE/pen/gJzqaG

The space between the images is usually sub 1 pixel (meaning the line is just a lighter shade of green). It's subtle and may be hard to see if you have a dull monitor.

In asking this question, I'm hoping to understand WHY it is occurring in a way that lets me make lots of repeating SVG backgrounds without issue. It's not just about the one image, so I want to avoid hacky solutions/workarounds if at all possible. For example, chopping 2 pixels off the edge fixes it 99% of the way, but not entirely, and it leaves me wondering what I would do if I actually needed those two pixels. This particular SVG looks okay like that but more complicated patterns would be knocked out of alignment.

Upvotes: 15

Views: 26380

Answers (3)

Paul LeBeau
Paul LeBeau

Reputation: 101820

It seems that some browsers do have trouble with repeating backgrounds made from SVG images.

One solution to this is to do the repeating inside the SVG instead. We can use a <pattern> element to define the repeating pattern and use that to fill a rectangle.

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="24">
  <defs>
    <pattern id="bg" patternUnits="userSpaceOnUse" width="130" height="24">
      <path fill="#A5EF8B" d="M0,12c32.5,0,32.5,12,65,12s32.5-12,65-12V0C97.5,0,92.9,12,65,12C32.5,12,20.7,0,0,0"/>
    </pattern>
  </defs>
  <rect width="100%" height="100%" fill="url(#bg)"/>
</svg>

And when used as a background-image to a <div>, it becomes:

div {
  margin: 4rem 0;
  height: 24px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%' height='24'%3E%3Cdefs%3E%3Cpattern id='bg' patternUnits='userSpaceOnUse' width='130' height='24'%3E%3Cpath fill='%23A5EF8B' d='M0,12c32.5,0,32.5,12,65,12s32.5-12,65-12V0C97.5,0,92.9,12,65,12C32.5,12,20.7,0,0,0'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='100%' height='100%' fill='url(%23bg)'/%3E%3C/svg%3E");
  background-size: 100% 24px;
  background-repeat: no-repeat;
}
<div></div>

Upvotes: 26

Krzysztof Antosik
Krzysztof Antosik

Reputation: 993

Each svg file has the following properties: "fill" and "stroke". Fill is a fill, and stroke is a contour. This space is both, which is by default transparencies. Edit the SVG file and add it to this code:

.st0 { fill: #A5EF8B; stroke: #A5EF8B; }

enter image description here

Upvotes: 0

enxaneta
enxaneta

Reputation: 33044

This is your svg used as a css background and there are no gaps. I've encoded the svg using this tool

Also please read Optimizing SVGs in data URIs

body{background-image: url("data:image/svg+xml,%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 130 24' xml:space='preserve' preserveAspectRatio='none'%3E%3Cstyle type='text/css'%3E .st0%7Bfill:%23A5EF8B;%7D %3C/style%3E%3Cpath class='st0' d='M0,12c32.5,0,32.5,12,65,12s32.5-12,65-12V0C97.5,0,92.9,12,65,12C32.5,12,20.7,0,0,0'/%3E%3C/svg%3E%0A");
background-size:130px 24px}

UPDATE

Apparently in Safari there is a gap between the repetitions of the svg background image. In the next example I'm setting the background-size:12vw (or any other multiple of vw) the gaps disappear.

In fact I've simplified the path as well.

body{  
  background-image: url("data:image/svg+xml,%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 6 130 26' width='100%' height='100%'%3E%3Cstyle type='text/css'%3E .st0%7Bstroke:%23A5EF8B; fill:none; stroke-width:12;%7D %3C/style%3E%3Cpath class='st0' d='M-1,12c32.5,0,32.5,12,65,12s32.5-12,69-12'/%3E%3C/svg%3E%0A");
background-size:12vw}

Upvotes: 2

Related Questions