clip-path:circle() 半径似乎没有正确计算

tec*_*ert 4 css geometry clip-path

每当我尝试使用 CSS circle()函数进行一些剪辑时,它一直困扰着我一段时间,如下所示:

.red {
  	width: 200px;
        height: 300px;
        background: red;
        border: 2px solid black;
        clip-path: circle(69%);  /*barely cuts off the corners of the .red div */
}

/*  the full circle will enclose the entire box at around 71% or (sqrt(2)/2 * 100%)
 per Mozilla documentation and not at 100% as one might expect */
Run Code Online (Sandbox Code Playgroud)
<div class='red'></div>
Run Code Online (Sandbox Code Playgroud)

半径似乎从未像我期望的那样计算。在查看 Mozilla MDN 参考(https://developer.mozilla.org/en-US/docs/Web/CSS/basic-shape)时,他们似乎按如下方式计算:



在此处输入图片说明



这对我来说似乎不正确。我想他们会计算包围元素矩形(div、img 等)的圆周半径,如下所示:



在此处输入图片说明



但事实并非如此。任何人都可以对此有所了解。这是某种错误还是我只是不理解这里的某些内容?

Tem*_*fif 7

它被定义为这样,他们从来没有打算计算您显示的半径。它也在规范中

为了更好地理解,让我们考虑一个正方形。如果你认为50%有价值,你可以有一个完美的圆圈

.red {
  width: 200px;
  height: 200px;
  background: red;
  clip-path: circle(50%);
  border:2px solid;
  box-sizing:border-box;
}
Run Code Online (Sandbox Code Playgroud)
<div class='red'></div>
Run Code Online (Sandbox Code Playgroud)

背后的想法是考虑下图:

在此处输入图片说明

R是您正在计算的“c”(绿线)并且r是使用的参考(紫线)。你可以很容易地看到r = R/sqrt(2)R = sqrt(w² + h²)。结合两者将给我们:

r = sqrt(w² + h²)/sqrt(2)
Run Code Online (Sandbox Code Playgroud)

这是您在 MDN 页面中看到的公式。

50%在正方形内使用此值将为我们提供逻辑圆:

 r/2 = sqrt(w² + h²)/(2*sqrt(2)) = sqrt(2*w²)/(2*sqrt(2)) = w/2 (or h/2)
Run Code Online (Sandbox Code Playgroud)

为了覆盖整个正方形,我们需要一个等于R/2is的值,r/sqrt(2) = r/1.41并且因为ris100%你会71%发现你

r = sqrt(w² + h²)/sqrt(2)
Run Code Online (Sandbox Code Playgroud)
 r/2 = sqrt(w² + h²)/(2*sqrt(2)) = sqrt(2*w²)/(2*sqrt(2)) = w/2 (or h/2)
Run Code Online (Sandbox Code Playgroud)

相同的逻辑适用于宽度和高度不同但引用保持不变的非方形形状:

r = sqrt(w² + h²)/sqrt(2)
Run Code Online (Sandbox Code Playgroud)

从上面我们可以得出结论,这71%是一个神奇的值,无论形状如何,它都会产生相同的输出,因为它依赖于包围元素矩形的圆周半径,而50%(或任何其他值)将给出不同的结果:

.red {
  width: 200px;
  height: 200px;
  background: red;
  clip-path: circle(calc(100% / 1.44)); /* a little bogger  than 1.4 to better see*/
  border:2px solid;
  box-sizing:border-box;
}
Run Code Online (Sandbox Code Playgroud)
<div class='red'></div>
Run Code Online (Sandbox Code Playgroud)

使用 50%

r = sqrt(w² + h²)/sqrt(2)
Run Code Online (Sandbox Code Playgroud)
.red {
  width: 200px;
  height: 200px;
  background: red;
  box-shadow:0 0 0 100px yellow;
  display:inline-block;
  clip-path: circle(71%); 
  margin: 70px;
}
Run Code Online (Sandbox Code Playgroud)

我们也可能认为任何大于 的值71%都是无用的,因为我们总是会给出一个比我们的元素大的圆。这是真的,但我们不应该忘记我们也有这个职位。

使用100%,200%甚至300%!

<div class='red'></div>
<div class='red' style="width:300px;"></div>
<div class='red' style="width:100px;"></div>
<div class='red' style="width:50px;"></div>
Run Code Online (Sandbox Code Playgroud)
.red {
  width: 200px;
  height: 200px;
  background: red;
  clip-path: circle(50%); 
  border:2px solid;
  box-sizing:border-box;
}
Run Code Online (Sandbox Code Playgroud)


我将考虑使用不同的属性来更好地清除radial-gradient.

<div class='red'></div>
<div class='red' style="width:300px;"></div>
<div class='red' style="width:100px;"></div>
<div class='red' style="width:50px;"></div>
Run Code Online (Sandbox Code Playgroud)
.red {
  width: 200px;
  height: 200px;
  background: red;
  border:2px solid;
  box-sizing:border-box;
}
Run Code Online (Sandbox Code Playgroud)

下面的代码是为了定义一个半径等于的圆,50%但它是无效的,因为我们不知道引用:

注意:此处不允许使用百分比;它们只能用于指定椭圆渐变的大小,而不是圆形渐变。之所以存在这种限制,是因为对于百分比应该相对于哪个维度有多种合理的答案。该模块的未来级别可能会提供使用百分比来调整圆圈大小的能力,也许可以对使用的维度进行更明确的控制。参考

我们正在处理矩形形状,因此我们可以使用高度、宽度、您正在计算的半径等。有很多选项,所以他们只是决定使其无效,但clip-path他们做出了决定并定义了一个参考百分数的使用。

顺便说一句,考虑到closest-side/等值,您可以更好地控制您的圈子farthest-side

下面总是给我们圆接触最近的边(contain与背景相同的方式)

<div class='red' style="clip-path: circle(100% at  0    50%)"></div>

<div class='red' style="clip-path: circle(200% at -100% 50%)"></div>

<div class='red' style="clip-path: circle(300% at -200% 50%)"></div>
Run Code Online (Sandbox Code Playgroud)
.box {
  width:200px;
  height:200px;
  border:1px solid;
  background:radial-gradient(circle 50%, red ,blue);
}
Run Code Online (Sandbox Code Playgroud)

下面将始终为我们提供接触最远边的圆圈(cover与背景相同)

<div class="box">

</div>
Run Code Online (Sandbox Code Playgroud)
.red {
  width: 200px;
  height: 200px;
  background: red;
  clip-path:circle(closest-side); 
  border:2px solid;
  box-sizing:border-box;
}
Run Code Online (Sandbox Code Playgroud)


结合位置,它们可以给出一些有趣的结果:

<div class='red'></div>
<div class='red' style="width:300px;"></div>
<div class='red' style="width:100px;"></div>
<div class='red' style="width:50px;"></div>
Run Code Online (Sandbox Code Playgroud)
.red {
  width: 200px;
  height: 200px;
  background: red;
  clip-path:circle(farthest-side); 
  border:2px solid;
  box-sizing:border-box;
}
Run Code Online (Sandbox Code Playgroud)