引言
对于 CSS
属性 border-radius
想必大家都很熟悉, 在日常开发中经常被用来为元素设置圆角, 然而它虽然表面上看起来似乎简单, 但深入研究边框圆角的实际运作方式却会发现其中的复杂性。在这篇文章中, 我们将探讨边框圆角的各种方面, 包括其绘制规则、在不同元素重叠情况下的表现, 以及与其他 CSS
属性相互作用的效果。通过深入理解边框圆角的工作原理, 我们将能够更好地利用这一特性, 为网页设计增添更多的创意和精彩。无论您是一个初学者还是一个经验丰富的开发者, 本文都将帮助您更好地掌握边框圆角...
一、简介
CSS
属性border-radius
最简单用法: 为元素设置一个外边框圆角

- 该属性值可以是任何的 CSS 长度单位 也可以是一个
百分百
该百分比的计算是相对于元素自身(包括元素的边框、padding
)
css
border-radius: 1em;
border-radius: 1rem;
border-radius: 10vw;
border-radius: 50%;
border-radius
是border-top-left-radius
、border-top-right-radius
、border-bottom-right-radius
和border-bottom-left-radius
几个属性的一个简写, 如下图, 它们分别表示一个元素在不同方位的一个圆角

- 下面我们来看下
border-radius
不同参数个数所带来的效果:
- 四个参数值(例:
border-radius: 10px 20px 30px 40px;
), 单独设置每个位置的圆角, 对于每个参数和位置对应关系, 个人记忆方法: 从左上角开始, 顺时针, 一一将每个位置和属性值进行对应

- 三个参数值(例:
border-radius: 10px 20px 30px;
), 等价于border-radius: 10px 20px 30px 20px;
, 对于每个参数和位置对应关系, 个人记忆方法: 从左上角开始, 顺时针, 一一将每个位置和属性值进行对应, 对于缺少的属性, 取对角值

- 两个参数(例:
border-radius: 10px 20px;
), 等价于border-radius: 10px 20px 10px 20px;
, 对于每个参数和位置对应关系, 个人记忆方法: 从左上角开始, 顺时针, 一一将每个位置和属性值进行对应, 对于缺少的属性, 取对角值

- 一个参数(例:
border-radius: 10px;
), 等价于border-radius: 10px 10px 10px 10px;
相当于为每个角设置相同的圆角
二、绘制规则
如下图, 我们设置了 border-top-left-radius: 10px
, 那么这个圆角的绘制可以看做是以元素左上角为圆心, 绘制了一个指定半径的圆, 然后从圆与矩形相交的 两个点
出发绘制矩形圆角

三、不等半径
在上文, 简单演示了下圆角的一个绘制规则!! 而文中的圆角是基于一个正圆进行绘制的, 当然绘制出来的圆角也是比较规整的!! 那么我们是否可以绘制一个不是那么规整的圆角呢? 是否可以基于一个椭圆来绘制圆角呢?
答案肯定是可以的, 其实 border-top-left-radius
等属性都是支持双值的, 例如: border-top-left-radius: 100px 50px
, 这两个值分别表示椭圆的 水平方向半径
、垂直方向半径

如果简写属性(border-radius
)需要设置不等半径的圆角, 可以通过 /
来分隔两组值, 而这两组值分别是各个方位在 水平方向半径
以及 垂直方向半径
, 例: border-radius: 10px 20px 30px 40px / 40px 30px 20px 10px

四、重叠怎么办?
开始前, 我们先看一个动图: 如下图所示, 当右上角圆角慢慢变大时, 会发现左上角的圆角会相应的变小; 您可以点击这里 css/shape 进行尝试

那么👆🏻这是为什么呢? 上文我们提到圆角的绘制可以理解为以一个椭圆为依据进行绘制的, 那么当椭圆之间出现了重叠, 它们会 等比例整体缩小
, 直到 不再有重叠
为止, 这也就造成了上图 👆🏻 的一个效果
- 首先假设有如下代码:
css
.demo {
width: 300px;
height: 100px;
border-radius: 50px 100px 150px 200px / 200px 150px 100px 50px;
}
- 那么如下图, 如果
按照设定
画出所有椭圆, 会发现它们之间是存在重叠的:

- 那么实际绘制的时候, 每个椭圆是会
等比例整体缩小
, 直到不再有重叠
为止, 如下图 👇🏻:

- 上文我们聊到, 为了防止重叠每个椭圆是会
等比例整体缩小
, 直到不再有重叠
为止, 那么你是否好奇, 它们整体缩小的比例又是怎么计算的呢? 其实就是计算出每条边长度
和同方向椭圆半径之和
的一个比例, 最后取最小值!!! 如下伪代码, 就是上文的DEMO
中, 每个边计算后的一个比例, 最终取最小值0.4
css
width: 300px;
height: 100px;
border-radius: 50px 100px 150px 200px / 200px 150px 100px 50px;
// 取最小值 0.4
Top: 300px / (50px + 100px) = 2
Right: 100px / (150px + 100px) = 0.4
Bottom: 300px / (150px + 200px) = 0.857
Left: 100px / (200px + 50px) = 0.4

五、和「borde」的奇妙组合
你知道吗? 当圆角(border-radius
)和边框(border
), 同时使用时将会有奇妙的效果:

上面动图, 最终样式如下:

其实就是 border-right
+ border-top-right
的一个组合效果:
css
.box {
width: 300px;
height: 100px;
border-right: 100px solid #4096ff;
border-top-right-radius: 300px 100px;
}

更多神奇组合, 可以点击这里 css/shape 进行尝试

六、与其他属性配合
- 与
background
一起使用, 会对背景进行裁切:
html
<style>
.demo1 {
width: 300px;
height: 100px;
border-radius: 50%;
background-color: #4096ff;
}
.demo2 {
width: 300px;
height: 100px;
border-radius: 50%;
background-image: url(./gameLb6.jpg);
}
</style>
<div class="demo1"></div>
<div class="demo2"></div>

- 与
box-shadow
一起使用, 实现各式立体图形:
html
<style>
.demo1 {
width: 300px;
height: 100px;
border-radius: 50%;
background-color:#4096ff;
box-shadow: 0 0 10px #000;
transition: all 0.1s;
}
.demo2 {
width: 300px;
height: 100px;
border-radius: 50%;
background-image: url(./gameLb6.jpg);
box-shadow: inset 0 0 10px #000;
}
</style>
<div class="demo1"></div>
<div class="demo2"></div>

- 支持和过渡(
transition
)属性一起使用, 再配合hover
完成平滑过渡效果:
html
<style>
.avatar {
width: 300px;
height: 300px;
background-image: url(./gameLb6.jpg);
border: 4px solid #0958d9;
border-radius: 51% 67% 56% 64%;
transition: all 1s;
&:hover {
border-radius: 95% 70% 100% 80%;
}
}
</style>
<div class="avatar"></div>

- 与动画(
keyframes
)一起使用, 实现炫酷的动态头像
html
<style>
@keyframes morph {
0% {
border-radius: 40% 60% 60% 40% / 60% 30% 70% 40%;
}
100% {
border-radius: 40% 60%;
}
}
@keyframes spin {
to {
transform: rotate(1turn);
}
}
.spin-container {
width: 300px;
height: 300px;
margin: auto;
animation: spin 12s linear infinite;
}
.shape {
height: 100%;
overflow: hidden;
border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
animation: morph 8s ease-in-out infinite both alternate;
}
.avatar {
width: 120%;
height: 120%;
margin: -10% 0 0 -10%;
background: url(./gameLb6.jpg) no-repeat center;
background-size: auto 100%;
animation: spin 12s linear infinite reverse;
}
</style>
<div class="spin-container">
<div class="shape">
<div class="avatar"></div>
</div>
</div>
