Kirill
Kirill

Reputation: 65

SVG stroke issue

I'm creating a chart with SVG. I've created it with three circle elements, and add one path(triangle) to make a blank space. But I don't how to hide a thin almost visible border at the bottom. Maybe I'm doing something wrong?

Here is my demo:

`https://codepen.io/Groude/pen/VgmVvG`

Here is a screenshot to better understand what I'm talking about:

enter image description here

SVG:

  <svg viewBox="0 0 32 32">
    <defs></defs>
    <circle
      r="16"
      cx="16"
      cy="16"
      class="circle--progress"
      stroke-dasharray="100 100"
    ></circle>
    <circle
      r="16"
      cx="16"
      cy="16"
      fill="none"
      stroke="#3FC364"
      stroke-dasharray="100 100"
    ></circle>
    <circle
      r="16"
      cx="16"
      cy="16"
      fill="none"
      stroke="#EDBB40"
      stroke-dasharray="66 100"
    ></circle>
    <circle
      r="16"
      cx="16"
      cy="16"
      fill="none"
      stroke="#FF8832"
      stroke-dasharray="33 100"
    ></circle>
    <path d="M16 16 L100 50 L200 -50 Z" fill="white"></path>
  </svg>
  <div class="text">
    <div class="text__percentage">100%</div>
    <div class="text__description">Sentiment<br />score</div>
  </div>
</div>

CSS

.wrapper {
  position: relative;
  width: 400px;
  height: 400px;
  padding: 20px 0;
  margin: 0 auto;
}

svg {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  transform: rotate(90deg);
}

circle {
  fill: transparent;
  stroke-width: 3;
}

.circle--progress {
  fill: transparent;
  stroke: #C4C4C4;
  stroke-width: 32;
  stroke-opacity: .25;
}

.text {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: sans-serif;
  text-align: center;
}

.text__percentage {
   font-size: 60px;
   font-weight: bold;
}

.text__description {
  font-size: 18px;
  font-weight: 500;
  line-height: 16px;
}

Upvotes: 3

Views: 965

Answers (2)

Wlodzislav K.
Wlodzislav K.

Reputation: 404

The issue seems in how browser(Chrome, Safary or others on the same engine) renders svg with border-radius:50%. Clipping it with circle mask doesn't help.

One solution is to make graphic look the same without cutting(masking) it with border-radiusto look circular. This will require tricking circles radius and stroke width for colored segments:

<circle
      r="15" <--
      cx="16"
      cy="16"
      fill="none"
      stroke="#3FC364"
      stroke-dasharray="100 100"
    ></circle>

circle {
  fill: transparent;
  stroke-width: 2; <--
}

And making progress circle to fit inside desired circle of the graph:

    <circle
      r="8" <--
      cx="16"
      cy="16"
      class="circle--progress"
      stroke-dasharray="100 100"
    ></circle>

.circle--progress {
  fill: transparent;
  stroke: #C4C4C4;
  stroke-width: 16; <-- 8 radius + 8 half stroke width= 16 visible radius
  stroke-opacity: .25;
}

See full example: https://codepen.io/anon/pen/zeogLV

If border-radius is needed to make the graphic blend better with the background - wrap it in div and apply border-radius to div.

See example https://codepen.io/anon/pen/exgOvm?editors=1100

I changed body background so clipping will be more clear.

Upvotes: 0

Austin
Austin

Reputation: 111

I assume you used Google Chrome or similar Blink- or Webkit-based browser to test this SVG image. Opening the page in Mozilla Firefox or Microsoft Edge does not display the very thin border you pointed out, so it is an issue with your browser and not your code. I suggest sending a bug report to Google about this issue.

In the meantime, to fix this issue for all browsers including Chrome, consider using the SVG <clipPath> element and apply it to all of the shapes except for the white triangle. Then, in the CSS remove the border-radius property in the svg selector.

<svg viewBox="0 0 32 32">
  <defs>
    <clipPath id="circle-viewport">
      <circle r="16" cx="16" cy="16" />
    </clipPath>
  </defs>
  <circle
    r="16"
    cx="16"
    cy="16"
    class="circle--progress"
    stroke-dasharray="100 100"
    clip-path="url(#circle-viewport)"
  ></circle>
  <circle
    r="16"
    cx="16"
    cy="16"
    fill="none"
    stroke="#3FC364"
    stroke-dasharray="100 100"
    clip-path="url(#circle-viewport)"
  ></circle>
  <circle
    r="16"
    cx="16"
    cy="16"
    fill="none"
    stroke="#EDBB40"
    stroke-dasharray="66 100"
    clip-path="url(#circle-viewport)"
  ></circle>
  <circle
    r="16"
    cx="16"
    cy="16"
    fill="none"
    stroke="#FF8832"
    stroke-dasharray="33 100"
    clip-path="url(#circle-viewport)"
  ></circle>
  <path d="M16 16 L100 50 L200 -50 Z" fill="white"></path>
</svg>

Upvotes: 1

Related Questions