Dániel Barta
Dániel Barta

Reputation: 1177

Gap in vertical repeat of svg background

I have a simple div, with an SVG set as background image with vertical repeat. On Chrome and Firefox, depending on the screen size, I see a gap in varying sizes (please resize the window).

https://jsfiddle.net/bartadaniel/ejtvy7po/9/

.bg {
  width: 50%;
  height: 2000px;
  display: block;
  background-repeat: repeat;
  background-size: contain;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='272' height='171' viewBox='0 0 272 171'> <rect class='cls-1' width='272' height='171' fill='green'/></svg>");
}
<div class="bg"></div>

Is there a reason for this?

Upvotes: 2

Views: 1832

Answers (4)

Gavin
Gavin

Reputation: 7976

If your SVG will still look acceptable with less anti-aliasing, you can change the anti-aliasing of the shapes in your SVG using the shape-rendering property. Example:

<rect shape-rendering="crispEdges">

You can use this on these elements: <circle>, <ellipse>, <line>, <path>, <polygon>, <polyline>, and <rect>.

Upvotes: 1

D&#225;niel Barta
D&#225;niel Barta

Reputation: 1177

Unfortunately, the only solution that reliably tackled this issue was to convert the SVG to a pixel-based format, like JPG. Apparently, the browsers have no problem scaling pixels but causes side effects at edges when scaling vector-based formats.

Upvotes: 1

Bryce Howitson
Bryce Howitson

Reputation: 7720

That's happening due to a combination of background-size:contain and the pixel dimensions of your svg.

You're seeing the browser try to scale the image so that nothing overflows the bounds of your <div>. When you combine that scaling with image pixel dimensions of 171 (can't be evenly multiplied into 2000px) you get lines showing you the sub pixels you're browser is trying to display.

Simply remove the background-size:contain to solve it.


Edit:

In the case where you need to contain width, there are a few tricks to help get a better result.

  1. Make the background image dimensions multiples of 10. Square would be best with something like 100x100px but it could also be a rectangle (try to get close to your target width) like 1000x100px.

  2. Set background-size: 100% auto instead of contain. This will stretch the image proportionalty to fill the container width.

  3. Use background-repeat: repeat-y to force a vertical repeat so the browser is only doing the math on one axis.

Upvotes: 4

thetont
thetont

Reputation: 810

It is a problem of subpixel rendering. Each browser rounds differently and SVG subpixel rendering is pretty messed up.

I suggest you to edit your SVG content to make it slightly bigger than your viewbox.

<svg xmlns='http://www.w3.org/2000/svg' width='272' height='171' viewBox='0 0 272 171'>
  <rect class='cls-1' y='-.5' width='272' height='172' fill='green'/>
</svg>

Obviously this trick doesn't work for all the background SVG, but might be useful in your case.

Upvotes: 2

Related Questions