百分比(%)、像素(px)或em单位的边框半径(Border-radius)

187
如果我使用像素或em单位的border-radius,即使值大于元素的最大边长,边缘的半径始终是一个圆弧或药丸形状。而当我使用百分比时,边缘半径是椭圆形的,并从元素每个边的中间开始,导致是椭圆形状。:

pixel (px) border radiuspercent (%) border-radius

Pixel value for border-radius :

div {
   background: teal;
   border-radius: 999px;
   width: 230px;
   height: 100px;
   padding: 40px 10px;
   box-sizing: border-box;
   font-family: courier;
   color: #fff;
 }
<div>border-radius:999px;</div>

边框半径的百分比值:

div {
  background: teal;
  border-radius: 50%;
  width: 230px;
  height: 100px;
  padding:40px 10px;
  box-sizing:border-box;
  font-family:courier;
  color:#fff;
}
<div>border-radius:50%;</div>

为什么使用百分比设置的边框半径与使用像素或em值设置的border-radius表现不同?

4个回答

291

边框半径:

首先,你需要理解border-radius属性接受2个值。这些值是定义角落形状四分之一椭圆X/Y轴上的半径。
如果只设置一个值,则第二个值等于第一个值。
因此,border-radius: x; 等价于 border-radius: x/x;

百分比值

参考W3C规范:CSS背景和边框模块3级 border-radius 属性,我们可以读到关于百分比值的内容:

百分比: 参考边框盒相应的尺寸。

所以,border-radius: 50%; 定义椭圆的半径如下:

  • X轴上的半径是容器宽度的50%
  • Y轴上的半径是容器高度的50%

Border-radius in percentage (%) make an ellipsis

像素和其他单位

对于边框半径使用一个值,除了百分比外(em、in、viewport相关单位、cm等),将始终产生具有相同X/Y半径的椭圆。换句话说,是个圆形

当你设置 border-radius: 999px; 时,圆的半径应为999px。但是在曲线重叠时,另一个规则被应用于减小圆的半径 ,使其等于最小边缘的一半大小。因此,在你的示例中,它等于元素高度的一半:50px。

Border-radius in pixels (px) make a pill shape


对于这个示例(带有固定大小的元素),无论是使用像素还是百分比都可以得到相同的结果。由于元素是230px x 100px,因此border-radius: 50%; 等价于 border-radius: 115px/50px;(两侧的50%):

.percent {
  border-radius: 50%;
}
.pixels {
  border-radius: 115px/50px;
}

/* For the demo : */
div {
  display: inline-block;
  background: teal;
  width: 230px;
  height: 100px;
  padding: 40px 10px;
  box-sizing: border-box;
  font-family: courier;
  font-size: 0.8em;
  color: #fff;
  text-align: center;
}
<div class="percent">border-radius: 50%;</div>
<div class="pixels">border-radius: 115px/50px;</div>


19
回答优秀。遗憾的是,百分比半径值在宽度和高度上被单独计算。这意味着我不能获得随对象大小缩放的圆角,而不知道对象的纵横比。如果将百分比应用于更大的对象尺寸,那不是很好吗? - Chris Dennis
7
这并不正确。就像楼主所说,你可以简单地使用border-radius: 999px;。这样你就可以获得圆形的边角,并确保它们随着元素的缩放而缩放。 - Gust van de Wal
17
但是我可能不想让盒子的两端呈半圆形。我希望能够指定 x 半径,例如相当于盒子宽度的 10%,并且将 y 半径设置为与 x 半径相等。 - Chris Dennis
5
嘿,你做过类似这样的自问自答的帖子吗?我很想读一下那些。 - Ced
5
但是百分比实际有效的是:border-radius: 50%/100%(在Chrome 60+61中测试过)。 - denns
显示剩余4条评论

8
要使其在视口大小上正确缩放,但又不需要任何 js 的情况下保持圆角,可以这样做:
border-radius: 3vmin;

然后它将始终按比例缩放到最小的尺寸,因此您永远不会有半圆形边缘的框,并且您无需使用任何JavaScript计算正确的百分比。

编辑:抱歉,我忘记了存在vmin,因此将其更改为使用vmin


1
注意:vmin单位是视口较小维度的1%。因此,在上面的示例中,这将是3%。 - Robert Newton
1
如果你想为边框半径设置最小和最大值,甚至可以使用类似于border-radius: clamp(1rem, 3vw, 3rem)的技术。在上下文中使用最合适的单位(如vw、vh、vmin、vmax等)。 - Seangle

4

只需将第一个值除以您想要的百分比即可。因此,如果您想要50%的边框半径,请编写:

border-radius: 25%/50%; 

另一个例子:

border-radius: 15%/30%;

你可以很容易地在js或SASS中进行数学计算。

5
那不就是宽度的25%和高度的50%吗?这并不等同于在X和Y方向上都是高度的50%。 - mpen
20
我不知道你正在做哪种数学,但这不是“纯粹的数学”。它是一个特别定义的边框半径的简写,与算术除法没有任何关系。https://www.w3.org/TR/css-backgrounds-3/#border-radius - user4698348

0
  1. 如果容器的高度已经定义,我们可以将其设置为定义高度的一半。
  2. 如果容器只有一行文本,比如芯片,1.2em的边框半径就足够了。
  3. 如果高度是动态的,我想没有直接的或者仅使用CSS的方法。

1
由于目前的回答不清楚,请编辑以添加更多细节,以帮助他人理解如何解决所提出的问题。您可以在帮助中心中找到有关撰写良好回答的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接