重叠的圆圈出血

Overlapping circles bleeding

我有一个 position:relative 绿色环,上面有一个 position:absolute 红色克隆 :before 和一个 position:absolute 白色克隆 :after 它覆盖了两者(因为它们是在同一个地方并具有相同的大小)。

问题是:它在测试的两个浏览器(Chrome 和 Firefox)上都呈现错误,我仍然可以在白色背景下看到 green/red 环面具。让带有 overflow:hidden 的绿色环部分解决了去除外出血的问题;但内部出血边界仍然存在。

为什么会这样,我怎样才能完全隐藏下面的圆圈?

Codepen

body {
  background: lavender;
}

#ring {
  position: relative;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  border: 50px solid green;
}

#ring:before {
  content: '';
  position: absolute;
  top: -50px;
  left: -50px;
  width: 100px;
  height: 100px;
  border: 50px solid red;
  border-radius: 50%;
}

#ring:after {
  content: '';
  position: absolute;
  top: -50px;
  left: -50px;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  border: 50px solid white;
}
<div id=ring></div>

更新: 这是完整(不是最小)场景的 link:Codepen 仅适用于更新后的 Google Chrome 目前;

在您的径向进度条方案中,您可以使用此处描述的方法:进度条的 . Using inline svg and animating the stroke-dasharray 属性。
适应您的用例,它看起来像这样:

body{background:lavender;}
svg{width:200px;height:200px;}
<svg viewbox="-2.5 -2.5 105 105">
  <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="25" stroke="#fff"/>
  <path fill="none" stroke-width="25" stroke="tomato"  stroke-dasharray="251.2,0" d="M50 10 a 40 40 0 0 1 0 80 a 40 40 0 0 1 0 -80">
    <animate attributeName="stroke-dasharray" from="0,251.2" to="251.2,0" dur="5s"/>           
  </path>
</svg>

请注意,在此示例中,动画是使用 SMIL 制作的。但是您也可以按照径向进度条答案中的描述使用 JS 来完成。


上一个回答:
如果您的目标是消除出血,一种解决方案是通过使伪元素边框更宽来隐藏它。
根据您的实际用例,此解决方案可能是合适的。

这是一个例子:

body{background:lavender}
#ring {
  position: relative;
  width: 100px;
  height: 100px;
  border-radius: 50%;
  border: 50px solid green;
}
#ring:before {
  content: '';
  position: absolute;
  top: -51px;
  left: -51px;
  width: 98px;
  height: 98px;
  border: 52px solid red;
  border-radius: 50%;
}
#ring:after {
  content: '';
  position: absolute;
  top: -52px;
  left: -52px;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  border: 54px solid white;
}
<div id="ring"></div>

问题的原因是限制(边界)像素中的抗锯齿。为了使圆的边界少像素化,只在圆内一半的像素被渲染semitransparents

问题是顶部圆圈下面的圆圈也在渲染半透明像素。 (当然是另一种颜色)。因此,半透明的白色呈现在半透明的红色之上(即呈现在半透明的绿色之上)。

最终结果是像素不是纯白色。

要解决问题的根源,您需要关闭抗锯齿功能,AFAIK 不支持边框(仅文本和开发中的图像)。而且,这样的解决方案会使圆圈变得非常丑陋

为了缓解它,您可以进行一些修改,包括大小、阴影或其他任何内容。

有关解决您在 CSS 中的原始问题的另一种方法(除了您已经使用 SVG 的出色方法),请参阅 this answer

以下代码片段的右侧是 @web-tiki svg ring with 2 clones of the same size/place (but different colors) with the anti-aliasing disabled (shape-rendering="crispEdges") just like @vals 提到的结果:

body {
  background: lavender;
  margin: 0;
  overflow: hidden;
}

div {
  width: 200px;
  height: 200px;
  display: inline-block;
  position: relative;
}

svg {
  width: 200px;
  height: 200px;
  position: absolute;
  top: 0;
  left: 0;
}

span {
  font-family: arial, sans-serif;
  text-align: center;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
  top: 45%;
}
<div>
<svg viewbox="-2.5 -2.5 105 105">
  <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="25" stroke="green"/>        
</svg>

<svg viewbox="-2.5 -2.5 105 105">
  <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="25" stroke="tomato"/>        
</svg>

<svg viewbox="-2.5 -2.5 105 105">
  <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="25" stroke="#fff"/>        
</svg><span><small>shape-rendering="auto"</small></span>
</div><div>
<svg viewbox="-2.5 -2.5 105 105" shape-rendering="crispEdges">
  <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="25" stroke="green"/>        
</svg>

<svg viewbox="-2.5 -2.5 105 105" shape-rendering="crispEdges">
  <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="25" stroke="tomato"/>        
</svg>

<svg viewbox="-2.5 -2.5 105 105" shape-rendering="crispEdges">
  <circle cx="50" cy="50" r="40" fill="transparent" stroke-width="25" stroke="#fff"/>        
</svg><span><small>shape-rendering="crispEdges"</small></span>
</div>

由于 OP 示例使用 :before:after 伪元素,我尝试在 svg 剪辑路径上应用相同的 shape-rendering="crispEdges",但在任何浏览器中都没有成功:Link

来源:MDN