user9631725
user9631725

Reputation:

SVG makes white lines in the browser

I made a 24x24-pixel logo. It consists of polygons that stand side by side.

I'm showing this in various sizes on my web page in the range of 40 pixels and 24 pixels.

enter image description here

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="katman_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<polygon points="6,20 4,16 2,20 "/>
<polygon points="4,16 2,12 0,16 "/>
<polygon points="6,12 4,8 2,12 "/>
<polygon points="8,8 6,4 4,8 "/>
<polygon points="10,12 8,8 6,12 "/>
<polygon points="14,12 12,8 10,12 "/>
<polygon points="18,12 16,8 14,12 "/>
<polygon points="22,12 20,8 18,12 "/>
<polygon points="12,16 10,12 8,16 "/>
<polygon points="20,16 18,12 16,16 "/>
<polygon points="4,16 6,20 8,16 "/>
<polygon points="2,12 4,16 6,12 "/>
<polygon points="0,16 2,20 4,16 "/>
<polygon points="4,8 6,12 8,8 "/>
<polygon points="6,4 8,8 10,4 "/>
<polygon points="8,8 10,12 12,8 "/>
<polygon points="16,8 18,12 20,8 "/>
<polygon points="18,12 20,16 22,12 "/>
<polygon points="10,12 12,16 14,12 "/>
<polygon points="8,16 10,20 12,16 "/>
<polygon points="16,16 18,20 20,16 "/>
<polygon points="20,16 22,20 24,16 "/>
<polygon points="10,20 8,16 6,20 "/>
<polygon points="14,20 12,16 10,20 "/>
<polygon points="18,20 16,16 14,20 "/>
<polygon points="22,20 20,16 18,20 "/>
</svg>

But white lines form between svg elements... For example:

enter image description here

Original svg file: bz.svg

I can't combine them because in some cases I color each one separately. How can I fix this?

Upvotes: 1

Views: 6891

Answers (2)

Paul LeBeau
Paul LeBeau

Reputation: 101820

shape-rendering will help in most cases. But it is not guaranteed. You still might find the odd white pixel. Plus it has the disadvantage that you lose the anti-aliasing on the outside edges. Leaving the sloped edges "jaggy".

Another solution, as others have suggested, is to add a thin stroke to your shapes. The width that that stroke needs to be will depend on the slope of the join line, and the 2D rendering engine that the browser uses.

A third solution is to merge adjacent triangles if they are the same colour. You can write a little javascript to do the merging. You probably don't have to worry about the adjacent triangles that have different colours. If the colours are different enough, the slight white line probably won't be noticeable.

A fourth option is similar. Instead of merging triangles, look for edges of triangles that later triangles abut against, and give those sides a "bulge". For example by using an extra point halfway along that side, that sticks out a bit. The idea is that the earlier triangle extends under the later one.

One final solution, I can think of, is to run a filter over the shape to remove the anti-aliasing artifacts.

The ideal filter for this would be a median filter, But unfortunately, SVG/CSS has no median filter. Michael Mullany created a very clever hack that simulates a median filter using a combination of the filter primitives that are available.

<svg version="1.1" id="katman_1" viewBox="0 0 24 24">
  <defs>
    <filter id="median">
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 1 0 0 0 0 0" result="1" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="1 0 0 0 0 0 0 0 0" result="2" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 1 0 0 0 0 0 0 0" result="3" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 1 0 0 0 0 0 0" result="4" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 0 1 0 0 0" result="5" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 0 0 0 0 1" result="6" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 0 0 0 1 0" result="7" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 0 0 1 0 0" result="8" preserveAlpha="true" />
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 1 0 0 0 0" result="9" preserveAlpha="true" />
      <feBlend in="1" in2="2" mode="lighten" result="a1"/>
      <feBlend in="1" in2="2" mode="darken" result="a2"/>
      <feBlend in="a2" in2="3" mode="lighten" result="a3"/>
      <feBlend in="a2" in2="3" mode="darken" result="a4"/>
      <feBlend in="a4" in2="4" mode="lighten" result="a5"/>
      <feBlend in="a4" in2="4" mode="darken" result="a6"/>
      <feBlend in="a6" in2="5" mode="lighten" result="a7"/>
      <feBlend in="a6" in2="5" mode="darken" result="a8"/>
      <feBlend in="a8" in2="6" mode="lighten" result="a9"/>
      <feBlend in="a8" in2="6" mode="darken" result="a10"/>
      <feBlend in="a10" in2="7" mode="lighten" result="a11"/>
      <feBlend in="a10" in2="7" mode="darken" result="a12"/>
      <feBlend in="a12" in2="8" mode="lighten" result="a13"/>
      <feBlend in="a13" in2="8" mode="darken" result="a14"/>
      <feBlend in="1" in2="2" mode="lighten" result="a15"/>
      <feBlend in="1" in2="2" mode="darken" result="a16"/>    
      <feBlend in="a1" in2="a3" mode="lighten" result="b1"/>
      <feBlend in="a1" in2="a3" mode="darken" result="b2"/>
      <feBlend in="b2" in2="a5" mode="lighten" result="b3"/>
      <feBlend in="b2" in2="a5" mode="darken" result="b4"/>
      <feBlend in="b4" in2="a7" mode="lighten" result="b5"/>
      <feBlend in="b4" in2="a7" mode="darken" result="b6"/>
      <feBlend in="b6" in2="a9" mode="lighten" result="b7"/>
      <feBlend in="b6" in2="a9" mode="darken" result="b8"/>
      <feBlend in="b8" in2="a11" mode="lighten" result="b9"/>
      <feBlend in="b8" in2="a11" mode="darken" result="b10"/>
      <feBlend in="b10" in2="a13" mode="lighten" result="b11"/>
      <feBlend in="b10" in2="a13" mode="darken" result="b12"/>
      <feBlend in="b12" in2="a15" mode="lighten" result="b13"/>
      <feBlend in="b12" in2="a15" mode="darken" result="b14"/>
      <feBlend in="b1" in2="b3" mode="lighten" result="c1"/>
      <feBlend in="b1" in2="b3" mode="darken" result="c2"/>
      <feBlend in="c2" in2="b5" mode="lighten" result="c3"/>
      <feBlend in="c2" in2="b5" mode="darken" result="c4"/>
      <feBlend in="c4" in2="b7" mode="lighten" result="c5"/>
      <feBlend in="c4" in2="b7" mode="darken" result="c6"/>
      <feBlend in="c6" in2="b9" mode="lighten" result="c7"/>
      <feBlend in="c6" in2="b9" mode="darken" result="c8"/>
      <feBlend in="c8" in2="b11" mode="lighten" result="c9"/>
      <feBlend in="c8" in2="b11" mode="darken" result="c10"/>
      <feBlend in="c10" in2="b13" mode="lighten" result="c11"/>
      <feBlend in="c10" in2="b13" mode="darken" result="c12"/>
      <feBlend in="c1" in2="c3" mode="lighten" result="d1"/>
      <feBlend in="d1" in2="c3" mode="darken" result="d2"/>
      <feBlend in="d2" in2="c5" mode="lighten" result="d3"/>
      <feBlend in="d2" in2="c5" mode="darken" result="d4"/>
      <feBlend in="d4" in2="c7" mode="lighten" result="d5"/>
      <feBlend in="d4" in2="c7" mode="darken" result="d6"/>
      <feBlend in="d6" in2="c9" mode="lighten" result="d7"/>
      <feBlend in="d6" in2="c9" mode="darken" result="d8"/>
      <feBlend in="d8" in2="c11" mode="lighten" result="d9"/>
      <feBlend in="d8" in2="c11" mode="darken" result="d10"/>
      <feBlend in="d1" in2="d3" mode="darken" result="e1"/>
      <feBlend in="e1" in2="d5" mode="darken" result="e2"/>
      <feBlend in="e2" in2="d7" mode="darken" result="e3"/>
      <feBlend in="e3" in2="d9" mode="darken" result="e4"/>
    </filter>
  </defs>

  <g filter="url(#median)">
    <polygon points="6,20 4,16 2,20 "/>
    <polygon points="4,16 2,12 0,16 "/>
    <polygon points="6,12 4,8 2,12 "/>
    <polygon points="8,8 6,4 4,8 "/>
    <polygon points="10,12 8,8 6,12 "/>
    <polygon points="14,12 12,8 10,12 "/>
    <polygon points="18,12 16,8 14,12 "/>
    <polygon points="22,12 20,8 18,12 "/>
    <polygon points="12,16 10,12 8,16 "/>
    <polygon points="20,16 18,12 16,16 "/>
    <polygon points="4,16 6,20 8,16 "/>
    <polygon points="2,12 4,16 6,12 "/>
    <polygon points="0,16 2,20 4,16 "/>
    <polygon points="4,8 6,12 8,8 "/>
    <polygon points="6,4 8,8 10,4 "/>
    <polygon points="8,8 10,12 12,8 "/>
    <polygon points="16,8 18,12 20,8 "/>
    <polygon points="18,12 20,16 22,12 "/>
    <polygon points="10,12 12,16 14,12 "/>
    <polygon points="8,16 10,20 12,16 "/>
    <polygon points="16,16 18,20 20,16 "/>
    <polygon points="20,16 22,20 24,16 "/>
    <polygon points="10,20 8,16 6,20 "/>
    <polygon points="14,20 12,16 10,20 "/>
    <polygon points="18,20 16,16 14,20 "/>
    <polygon points="22,20 20,16 18,20 "/>
  </g>
</svg>

Upvotes: 3

Chris W.
Chris W.

Reputation: 23280

Shape Rendering is your culprit amigo.

Just add shape-rendering="crispEdges" to the svg declaration (see in the source example below)... ....or as CSS to hit more than one if you like at the element level like;

svg {
  shape-rendering: crispEdges;
}

Enjoy, and cool graphic ;)

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="katman_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve" 
shape-rendering="crispEdges"> <!-- **** YOUR NEW FRIEND **** -->
  <polygon points="6,20 4,16 2,20 "/>
  <polygon points="4,16 2,12 0,16 "/>
  <polygon points="6,12 4,8 2,12 "/>
  <polygon points="8,8 6,4 4,8 "/>
  <polygon points="10,12 8,8 6,12 "/>
  <polygon points="14,12 12,8 10,12 "/>
  <polygon points="18,12 16,8 14,12 "/>
  <polygon points="22,12 20,8 18,12 "/>
  <polygon points="12,16 10,12 8,16 "/>
  <polygon points="20,16 18,12 16,16 "/>
  <polygon points="4,16 6,20 8,16 "/>
  <polygon points="2,12 4,16 6,12 "/>
  <polygon points="0,16 2,20 4,16 "/>
  <polygon points="4,8 6,12 8,8 "/>
  <polygon points="6,4 8,8 10,4 "/>
  <polygon points="8,8 10,12 12,8 "/>
  <polygon points="16,8 18,12 20,8 "/>
  <polygon points="18,12 20,16 22,12 "/>
  <polygon points="10,12 12,16 14,12 "/>
  <polygon points="8,16 10,20 12,16 "/>
  <polygon points="16,16 18,20 20,16 "/>
  <polygon points="20,16 22,20 24,16 "/>
  <polygon points="10,20 8,16 6,20 "/>
  <polygon points="14,20 12,16 10,20 "/>
  <polygon points="18,20 16,16 14,20 "/>
  <polygon points="22,20 20,16 18,20 "/>
</svg>

Upvotes: 3

Related Questions