简体   繁体   中英

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:

在此输入图像描述

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;
}

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>

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-radius to 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM