重叠的圆圈出血
Overlapping circles bleeding
我有一个 position:relative
绿色环,上面有一个 position:absolute
红色克隆 :before
和一个 position:absolute
白色克隆 :after
它覆盖了两者(因为它们是在同一个地方并具有相同的大小)。
问题是:它在测试的两个浏览器(Chrome 和 Firefox)上都呈现错误,我仍然可以在白色背景下看到 green/red 环面具。让带有 overflow:hidden
的绿色环部分解决了去除外出血的问题;但内部出血边界仍然存在。
为什么会这样,我怎样才能完全隐藏下面的圆圈?
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
我有一个 position:relative
绿色环,上面有一个 position:absolute
红色克隆 :before
和一个 position:absolute
白色克隆 :after
它覆盖了两者(因为它们是在同一个地方并具有相同的大小)。
问题是:它在测试的两个浏览器(Chrome 和 Firefox)上都呈现错误,我仍然可以在白色背景下看到 green/red 环面具。让带有 overflow:hidden
的绿色环部分解决了去除外出血的问题;但内部出血边界仍然存在。
为什么会这样,我怎样才能完全隐藏下面的圆圈?
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 目前;
在您的径向进度条方案中,您可以使用此处描述的方法:进度条的
适应您的用例,它看起来像这样:
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