径向渐变显示一些背线、间隙、空间或边距

Radial gradient shows some backlines, gap, spaces or margins

我是 radial-gradient 的新手,我不知道立方体之间的那些背线或空间是什么?如何删除它们?

* {margin: 0; outline: 0; border: 0;}
.round {
  background: radial-gradient(circle at 0 100%, rgba(204, 0, 0, 0) 70%, #c00 71%),
              radial-gradient(circle at 100% 100%, rgba(204, 0, 0, 0) 70%, #c00 71%), 
              radial-gradient(circle at 100% 0, rgba(204, 0, 0, 0) 70%, #c00 71%), 
              radial-gradient(circle at 0 0, rgba(204, 0, 0, 0) 70%, #c00 71%);
  background-position: bottom left, bottom right, top right, top left;
  background-size: 50% 50%;
  background-repeat: no-repeat;
  width: 300px;
  height: 300px;
  padding: 10%;
  transform: rotate(45deg);
}
p {
  transform: rotate(-45deg);
  width: 100px;
  margin: 100px;
}
<div class="round">
  <p>By using radial gradients, you can simulate rounded corners with a negative radius. Just in this case,</p>
</div>

您的代码片段中存在两个问题,当我们修复这两个问题时,出现在中间的奇怪间隙或线条将完全消失..

  • 问题 1: 您在元素上设置 padding: 10% 而不是固定值。当我们以百分比形式给出值时,就 rounding-off 逻辑而言,我们受 UA 的支配。每个 UA 都有自己的 rounding-off 逻辑。例如盒子的包含块的宽度是 510px,现在 10% 变成 51px。元素的实际宽度包括其填充,因此此处它将变为 351px,当 UA 尝试为 background-size 计算宽度的 50% 时,结果值为 175.5px这就是收获所在Some browsers round it down to 175px, some like FF has unique logic which rounds down some but rounds up the others, some just round it up etc。当该值向下舍入时,两个背景块的总大小变为 350px,但框的实际宽度为 351px,这 1px 的差异就是您看到的差距。
  • 问题 2: 当我们对元素应用变换时,这种间隙总是会出现。 我的感觉是这个跟元素的backface有关系因为当我们设置backface-visibilityhidden。我们在答案的底部添加了详细的解释。 (这在 Chrome 中进行了测试,但应该可以正常工作。如果没有,则没有解决方案。

在下面的代码片段中,我已经解决了这两个问题,您可以看到它是如何正常工作的。 backface-visibility: hidden 还有一个额外的问题。当您在容器元素上设置它时,该元素内的所有文本都会变得模糊。因此,最好使用伪创建背景,因为它不会影响 p 元素的显示。

* {
  margin: 0;
  outline: 0;
  border: 0;
}
.round {
  position: relative;
  width: 300px;
  height: 300px;
  padding: 30px;
}
.round:after {
  position: absolute;
  content: '';
  height: 100%;
  width: 100%;
  top: 0px;
  left: 0px;
  background: radial-gradient(circle at 0 100%, rgba(204, 0, 0, 0) 70%, #c00 71%), radial-gradient(circle at 100% 100%, rgba(204, 0, 0, 0) 70%, #c00 71%), radial-gradient(circle at 100% 0, rgba(204, 0, 0, 0) 70%, #c00 71%), radial-gradient(circle at 0 0, rgba(204, 0, 0, 0) 70%, #c00 71%);
  background-position: bottom left, bottom right, top right, top left;
  background-size: 50% 50%;
  background-repeat: no-repeat;
  transform: rotate(45deg);
  backface-visibility: hidden;
  z-index: -1;
}
p {
  width: 125px;
  margin: 85px;
}
<div class="round">
  <p>By using radial gradients, you can simulate rounded corners with a negative radius. Just in this case,</p>
</div>


一样,问题2也可以通过将元素的渲染从CPU移到GPU层来解决。这通常是 通过将 translateZ(1px) 添加到转换堆栈来完成的。正如他还指出的那样,在某些机器中,这也改进了 anti-aliasing。

* {
  margin: 0;
  outline: 0;
  border: 0;
}
.round {
  position: relative;
  width: 300px;
  height: 300px;
  padding: 30px;
  background: radial-gradient(circle at 0 100%, rgba(204, 0, 0, 0) 70%, #c00 71%), radial-gradient(circle at 100% 100%, rgba(204, 0, 0, 0) 70%, #c00 71%), radial-gradient(circle at 100% 0, rgba(204, 0, 0, 0) 70%, #c00 71%), radial-gradient(circle at 0 0, rgba(204, 0, 0, 0) 70%, #c00 71%);
  background-position: bottom left, bottom right, top right, top left;
  background-size: 50% 50%;
  background-repeat: no-repeat;
  transform: rotate(45deg) translateZ(1px);
}
p {
  transform: rotate(-45deg) translateZ(-1px);
  width: 125px;
  margin: 85px;
}
<div class="round">
  <p>By using radial gradients, you can simulate rounded corners with a negative radius. Just in this case,</p>
</div>


问题 2 的解释:

这里有更详细的解释 可能是第二个问题的原因问题。感谢 vals 在提出这个原因时提供的出色帮助。

假设两个不同的梯度直接渲染到canvas,没有中间缓冲区。沿着作为两个梯度之间边界的对角线,有一些像素仅被第一个梯度覆盖 50%。稍后,第二个梯度也将覆盖 50%。

这应该等于全像素 (50% + 50%)。但是 渲染它的方式是使用 0.5 的 alpha。问题是,在这种情况下,运算是乘法而不是加法,并且使用 alpha 0.5 渲染两次只会给出一个alpha 为 0.75,而不是 1。所以像素在一定程度上仍然是透明的,并且背景显示。

这可以通过在 Chrome 开发控制台中启用 "Show Paint Rects" 和 "Show Layer Borders" 选项来验证(某种程度上)。对于有问题的 片段,没有创建层 。也就是说,元素 以其旋转形式 绘制,因此两个渐变图像之间的分离点沿对角线。由于它是沿着对角线的,因此必须为每个图像分配 50% 的像素。

GPU 渲染 在旋转之前在中间缓冲区(或层)上完成,因此像素落在一个均匀的边界。它还可以使用 sub-pixel 渲染。

这也可以通过使用 Chrome 开发控制台来验证。附加任何 3D 变换 属性(如 backface-visibilitytranslateZ)会导致创建图层。现在,元素首先以其正常形式(无旋转)绘制,然后单独旋转图层。所以,分离点是沿着一条直线而不是对角线,所以不需要 50-50 逻辑。当我们检查答案中的两个片段时,我们可以看到元素周围有一个 orange-ish 边框(相关片段不会出现)。这是图层的边框(我们通过之前的设置启用了它的显示)。