径向渐变显示一些背线、间隙、空间或边距
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-visibility
到hidden
。我们在答案的底部添加了详细的解释。 (这在 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-visibility
、translateZ
)会导致创建图层。现在,元素首先以其正常形式(无旋转)绘制,然后单独旋转图层。所以,分离点是沿着一条直线而不是对角线,所以不需要 50-50 逻辑。当我们检查答案中的两个片段时,我们可以看到元素周围有一个 orange-ish 边框(相关片段不会出现)。这是图层的边框(我们通过之前的设置启用了它的显示)。
我是 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 to175px
, 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-visibility
到hidden
。我们在答案的底部添加了详细的解释。 (这在 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>
与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-visibility
、translateZ
)会导致创建图层。现在,元素首先以其正常形式(无旋转)绘制,然后单独旋转图层。所以,分离点是沿着一条直线而不是对角线,所以不需要 50-50 逻辑。当我们检查答案中的两个片段时,我们可以看到元素周围有一个 orange-ish 边框(相关片段不会出现)。这是图层的边框(我们通过之前的设置启用了它的显示)。