关于 border-radius 你很可能不知道的一些事

关于 border-radius 你很可能不知道的一些事

三葉Leaves Author

前言

我在试图创建一个胶囊形状的时候遇到了这个问题。
对于一个矩形而言,如果你只是单纯的这么做:

1
border-radius: 50%;

最终你只会得到一个椭圆:

要生成一个合格的胶囊,圆角的水平和垂直半径都得等于盒子的较短边的一半。

dbc94546cd20e7b898b1d83191d11a6.jpg
dbc94546cd20e7b898b1d83191d11a6.jpg

可是事实上,当你在属性里使用百分数的时候,默认对应的是对应边(也就是水平半径是盒子 width 的一半,垂直半径是 height 的一半)。而如果想要制作胶囊,你想要的是垂直半径和水平半径都是盒子垂直边的一半。

但除非使用变量,你几乎无法做成这件事。我学到了一个比较讨巧的办法是这样做:

1
2
/* 设置成一个很大的值 */
border-radius: 9999px;

如此一来,真的能创建一个完美的胶囊。但是为什么可以?
这个让我对背后的原理滋生了浓厚的兴趣。经过一系列探究,我已经得到了答案。探究用到的案例代码我会放在文末。

基础知识

border-radius 的一个最完整的写法是这样的:

dbc94546cd20e7b898b1d83191d11a6.jpg
dbc94546cd20e7b898b1d83191d11a6.jpg

1
2
3
4
5
/*
下面的几个值分别表示:
角1的水平半径10px 角2的水平半径20px 角3的水平半径30px 角4的水平半径40px / 角1的垂直半径15px 角2的垂直半径25px 角3的垂直半径35px 角4的垂直半径45px
*/
border-radius: 10px 20px 30px 40px / 15px 25px 35px 45px;

角的次序就是从左上角开始顺时针转一圈。

一个冲突情况

对于一个 400x200 的盒子,如果我把圆角设置成这样:

1
border-radius: 200px 0px 0px 200px / 150px 0px 0px 150px;

你会发现左上角和左下角的垂直半径都超过了盒子的高度,也就是像下图这样:

一个冲突情况
一个冲突情况

那到最后到底会怎么渲染呢?先看答案:

没错,在这种冲突下,居然达成了某种平衡,使得两个角的垂直半径看起来都像是 height 的一半,也就是 100px。

原理

经过仔细查阅资料,我明白了一个重要的相关原理:

当相邻角的半径之和超过相应边的长度时,浏览器会按比例缩小所有半径值直到相加等于对应边长度,以确保它们能够正确渲染。

也就是说对于一个 400x200 的盒子,如果这样设置:

1
border-radius: 200px 0px 0px 200px / 300px 0px 0px 300px;

那浏览器会这样算:

两个边的垂直半径和两个边的垂直半径和 == 300300 ++ 300300 == 600600

实际的height实际的 height == 200200

得出应该缩小3得出应该缩小 3 倍

所以最终的垂直半径都为:

300300 ÷÷ 33 == 100100

值得注意的是,水平半径也会发生变化

最终的水平半径最终的水平半径 == 200200 ÷÷ 33

原因在于:
当浏览器调整 border-radius 值时,它会:

  1. 保持原始的水平:垂直半径比例
  2. 同比例缩放两个方向的半径

结论

经过上面的探究,就能知道为什么圆角半径设置的很大的时候,能巧妙制作出胶囊了:

浏览器会同比例缩放水平半径和垂直半径,缩放的比例是由盒子的较短边决定的,这是因为在缩小比例的时候,要达到短边的长度,短边需要更大的缩放比。所以最后就发现圆角值能很巧的等于较短边的一半啦。

测试用例

测试的时候调整 .box 的圆角值即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<!--

Copyright © 2025 LeavesWebber



SPDX-License-Identifier: MPL-2.0



Feel free to contact LeavesWebber@outlook.com

-->

<!DOCTYPE html>

<html lang="en">

  <head>

    <meta charset="UTF-8" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <title>Document</title>

  </head>

  <body>

    <style>

      * {

        margin: 0;

        padding: 0;

        box-sizing: border-box;

        position: relative;

      }

      body {

        height: 100vh;

        background-color: #333;

      }

      .box {

        box-sizing: border-box;

        width: 400px;

        height: 200px;

        top: 1%;

        left: 50%;

        position: absolute;

        transform: translateX(-50%);

        background-color: #ab8df7cc;

        border: #bdbdbd 2px solid;

        /* 调整这个值,来探究圆角的各种情况 */

        border-radius: 200px 0px 0px 200px / 300px 0px 0px 300px;

    }

      /* .box3 {

        box-sizing: border-box;

        width: 400px;

        height: 200px;

        top: 1%;

        left: 50%;

        position: absolute;

        transform: translateX(-50%);

        border: #f20606 2px solid;

        border-radius: 0px 0px 0px 200px / 0px 0px 0px 150px;

    } */

      .box2 {

        width: 400px;

        height: 200px;

        display: flex;

        flex-wrap: wrap;

        top: 1%;

        left: 50%;

        position: absolute;

        transform: translateX(-50%);

        background-color: #ab8df748;

      }

      .grid {

        width: 25%;

        height: 50%;

        box-sizing: border-box;

        border: #c9c9c9 1px dashed;

      }

    </style>

    <div class="box"></div>

    <!-- <div class="box3"></div> -->

    <div class="box2">

      <div class="grid"></div>

      <div class="grid"></div>

      <div class="grid"></div>

      <div class="grid"></div>

      <div class="grid"></div>

      <div class="grid"></div>

      <div class="grid"></div>

      <div class="grid"></div>

    </div>

  </body>

</html>
  • 标题: 关于 border-radius 你很可能不知道的一些事
  • 作者: 三葉Leaves
  • 创建于 : 2025-05-08 00:00:00
  • 更新于 : 2025-05-13 23:50:35
  • 链接: https://blog.oksanye.com/c78e78c18ee9/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
关于 border-radius 你很可能不知道的一些事