Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

css

svg

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.

like image 933
TelFiRE Avatar asked May 26 '19 00:05

TelFiRE


People also ask

How do you repeat an SVG in HTML?

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.

Can I use SVG as background image CSS?

SVG images can be used as background-image in CSS as well, just like PNG, JPG, or GIF. All the same awesomeness of SVG comes along for the ride, like flexibility while retaining sharpness. Plus you can do anything a raster graphic can do, like repeat.

What does the repeat-X property of an image do?

repeat-x: This property is used to repeat the background image horizontally.


2 Answers

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>
like image 75
Paul LeBeau Avatar answered Oct 22 '22 08:10

Paul LeBeau


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}
like image 45
enxaneta Avatar answered Oct 22 '22 06:10

enxaneta