要不重新认识下「border-radius」?

引言

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

一、简介

  1. CSS 属性 border-radius 最简单用法: 为元素设置一个外边框 圆角
  1. 该属性值可以是任何的 CSS 长度单位 也可以是一个 百分百 该百分比的计算是相对于元素自身(包括元素的边框、padding)
css 复制代码
border-radius: 1em;
border-radius: 1rem;
border-radius: 10vw;
border-radius: 50%;
  1. border-radiusborder-top-left-radiusborder-top-right-radiusborder-bottom-right-radiusborder-bottom-left-radius 几个属性的一个简写, 如下图, 它们分别表示一个元素在不同方位的一个圆角
  1. 下面我们来看下 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 进行尝试

那么👆🏻这是为什么呢? 上文我们提到圆角的绘制可以理解为以一个椭圆为依据进行绘制的, 那么当椭圆之间出现了重叠, 它们会 等比例整体缩小, 直到 不再有重叠 为止, 这也就造成了上图 👆🏻 的一个效果

  1. 首先假设有如下代码:
css 复制代码
.demo {
  width: 300px;
  height: 100px;
  border-radius: 50px 100px 150px 200px / 200px 150px 100px 50px;
}
  1. 那么如下图, 如果 按照设定 画出所有椭圆, 会发现它们之间是存在重叠的:
  1. 那么实际绘制的时候, 每个椭圆是会 等比例整体缩小, 直到 不再有重叠 为止, 如下图 👇🏻:
  1. 上文我们聊到, 为了防止重叠每个椭圆是会 等比例整体缩小, 直到 不再有重叠 为止, 那么你是否好奇, 它们整体缩小的比例又是怎么计算的呢? 其实就是计算出每条边 长度同方向椭圆半径之和 的一个比例, 最后取最小值!!! 如下伪代码, 就是上文的 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 进行尝试

六、与其他属性配合

  1. 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>
  1. 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>
  1. 支持和过渡(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>
  1. 与动画(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>

七、参考

相关推荐
GoldKey2 小时前
gcc 源码阅读---语法树
linux·前端·windows
Xf3n1an3 小时前
html语法
前端·html
张拭心3 小时前
亚马逊 AI IDE Kiro “狙击”Cursor?实测心得
前端·ai编程
烛阴4 小时前
为什么你的Python项目总是混乱?层级包构建全解析
前端·python
@大迁世界4 小时前
React 及其生态新闻 — 2025年6月
前端·javascript·react.js·前端框架·ecmascript
红尘散仙5 小时前
Rust 终端 UI 开发新玩法:用 Ratatui Kit 轻松打造高颜值 CLI
前端·后端·rust
新酱爱学习5 小时前
前端海报生成的几种方式:从 Canvas 到 Skyline
前端·javascript·微信小程序
袁煦丞5 小时前
把纸堆变数据流!Paperless-ngx让文件管理像打游戏一样爽:cpolar内网穿透实验室第539个成功挑战
前端·程序员·远程工作
慧慧吖@6 小时前
关于两种网络攻击方式XSS和CSRF
前端·xss·csrf
徐小夕6 小时前
失业半年,写了一款多维表格编辑器pxcharts
前端·react.js·架构