重叠的圆圈出血

时间:2016-03-29 09:02:03

标签: css css3 svg css-shapes pseudo-element

我有一个position:relative绿色环,其中position:absolute红色克隆:beforeposition:absolute白色克隆:after覆盖了两个(因为它们位于相同的地方,并有相同的大小)。

问题是:它在测试的两个浏览器(Chrome和Firefox)上都会出现问题,我仍然可以看到白色遮罩下的绿色/红色环。让带有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>
&#13;
&#13;
&#13;

更新:此处是完整(非最小)方案的链接:Codepen目前只在更新的Google Chrome上运行;

3 个答案:

答案 0 :(得分:6)

在径向进度条方案中,您可以使用此处描述的方法:Circular percent progress bar。使用inline svg并为进度条设置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>

答案 1 :(得分:4)

问题的原因是限制(边框)像素中的抗锯齿。为了使圆的边界更少像素化,仅在圆圈中间的像素将被渲染为半透明父母

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

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

要解决问题的根源,您需要关闭抗锯齿,AFAIK不具有边框(只有文本和开发中的图像)。此外,这样的解决方案会让圈子变得非常丑陋

要减轻它,你可以做几个黑客,包括大小,阴影或其他任何东西。

另一种解决CSS原始问题的方法(除了你已经使用SVG的优秀问题),请参阅this answer

答案 2 :(得分:1)

在以下代码段的右侧是@web-tiki svg环的结果,其中2个克隆具有相同的大小/位置(但颜色不同)且禁用了抗锯齿(shape-rendering="crispEdges")就像@vals提到的那样:

&#13;
&#13;
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%;
}
&#13;
<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>
&#13;
&#13;
&#13;

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

来源:MDN