CSS 与布局 / 圆角三部曲:一个角的二十年 / border-radius:一行写四个角 待审核 2 / 5
border-radius · 圆角本体

border-radius:一行写四个角

border-radius 把上一页那套切图工程压成一行声明:圆角不再是图片资产,而是浏览器在渲染时画出的矢量弧,能继承、能动画、随字号与主题色变化。它看似简单,背后却是 8 个半径——四个角各有水平与垂直两个。本页拆解它的全部语法与副作用:四角的展开顺序斜杠分写的椭圆角半径超界时的等比收缩裁剪与协同

1 · 四角语法的展开顺序

border-radius 的 1~4 个值不是 margin / padding 那套「上右下左」,而是四个角,从左上角起顺时针:TL → TR → BR → BL。默认值对角补齐:1 值四角相同;2 值分给「主对角线 / 副对角线」,即 TL·BR 与 TR·BL;3 值分给「TL / 两个副对角 / BR」。每个角有水平与垂直两个半径,默认同步(水平等于垂直,正圆弧);把某个角单独切到分开,该角的两个半径各自可调,shorthand 用 / 前后分写,见 §2。

图 1-1 · 1~4 值的顺时针展开与四个 longhand 的对应。可拖滑块观察 shorthand 自动塌缩成最短写法,并把单个角切到水平 / 垂直分开。

1.1 · 四个 longhand 与各自的两个半径

shorthand border-radius 把这四个 longhand(及它们各自的水平 / 垂直分量)合写,水平与垂直用 / 分隔,见 §2。
longhand 管哪个角 取值
border-top-left-radius 左上 可接 1 或 2 个值:水平 垂直。一个值时水平等于垂直(正圆弧)
border-top-right-radius 右上 同上
border-bottom-right-radius 右下 同上
border-bottom-left-radius 左下 同上

注 · 补齐规则与 margin / padding 不同。border-radius 补的是对角(2 值等于两条对角线),margin 补的是对边。把 TL 与 BR 设成一样、TR 与 BL 设成另一样,shorthand 会塌缩成两个值。

2 · 椭圆角与斜杠语法

每个角的弧是一段椭圆弧,有独立的水平半径与垂直半径。两者相等时弧是正圆,不等时是被拉长的椭圆。在 shorthand 里用 / 分隔:斜杠前是四个角的水平半径,斜杠后是四个角的垂直半径,如 border-radius: 40px 20px / 20px 40px

图 2-1 · 同一个角的水平与垂直半径分开取值时的椭圆弧。可分别拖两个滑块观察弧形从正圆变为椭圆。

建议 · 百分比相对 border box 的宽与高计算,因此四角都取 50% 时正方形得正圆、长方形得椭圆(水平半径为宽的一半、垂直半径为高的一半)。做胶囊按钮(两端半圆)更稳的写法是 border-radius: 9999px:一个大到必定被收缩算法压回「半个短边」的长度值,无论盒子多宽两端都恰好是半圆,不像 50% 那样在长方形上变成椭圆。

3 · 半径超界时的等比收缩

如果相邻两个角的半径之和超过它们共享那条边的长度,弧就会重叠、画不出来。规范规定此时浏览器不报错、不裁断,而是为所有半径找一个统一的缩放系数

f=miniLiSif = \min_i \frac{L_i}{S_i}

其中 LiL_i 是第 ii 条边的长度,SiS_i 是该边两端在这条边方向上的那两个半径之和——横边取两端的水平半径,竖边取两端的垂直半径。若 f<1f < 1,把每个半径都乘以 ff;否则不动。结果是所有半径等比收缩,比例不失真。

图 3-1 · 半径推到超过盒子尺寸时的收缩系数与实际渲染。可拖滑块越过阈值观察 ff 从 1 开始下降。

注 · 若改为每个角各自 clamp,相邻半径不同时会出现突变拐点、弧线不再平滑相接;统一系数保证所有角按同一比例缩小,相邻弧仍平滑过渡。这也是 9999px 胶囊写法可靠的原因:它必定触发收缩,被压回恰好半个短边。

4 · 裁剪与协同

圆角不改变盒子在布局里占的方形区域,却会收缩它的命中区域。CSS Backgrounds 3 §4.3 要求「把绘制或事件处理裁剪到边框、内边距或内容边缘的其他效果,必须裁到各自对应的曲线」,并点名 pointer events 裁到弯曲后的边框边缘 [1];规范还专门加了一条注记,提醒作者留意圆角会减小可交互面积,在有最小触控目标尺寸要求的平台上可能需要加大宽高。Chrome 151 实测:200×200 的盒子设 border-radius: 60px 后,(10,10)(10, 10) 处的命中落到 body(30,30)(30, 30) 才命中盒子;corner-shape: scoop 凹进去的那块同样点不到(核对于 2026-08)。

要让内容也被圆角裁掉,需 overflow: hidden(或 clip / auto)。backgroundbox-shadow 默认就跟随圆角轮廓。

图 4-1 · 圆角对 background、border、box-shadow、outline 与子内容的作用差异。可切换 overflow 观察子内容何时被裁;本图的 outline 另设了 outline-offset: 3px 以便与边框区分。

警示 · overflow: visible 下子内容的方角会探出圆角轮廓,这是最常见的圆角失效来源:父级设了 border-radius 却没设 overflow: hidden,里面的图片或背景在角上露出直角。反过来 overflow: hidden 也会切断子级的 box-shadow 外扩,需要圆角裁剪又要让阴影外溢时,常用额外一层包裹分离这两件事。

overflow: hidden 只裁那些以它为包含块的绝对定位子级。若容器自身是 position: static,又没有 transform / filter / contain 这类会生成包含块的属性,绝对定位子级的包含块另在上层,不受它裁剪。Chrome 151 实测:static 容器内 left: 300px 的绝对定位子级完整可见且可点,同一结构把容器改成 position: relative 后即被裁掉(核对于 2026-08)。

4.1 · 圆角对各属性的影响

「跟随」指该效果沿圆角曲线绘制或裁剪。命中区域一栏是最容易记反的:布局不变,但可点区域跟着轮廓收缩。
属性 / 行为 跟随圆角? 要点
background 跟随 背景被裁进圆角轮廓(默认 background-clip: border-box
box-shadow 跟随 外阴影与内阴影都沿圆角轮廓绘制
border 跟随 边框内外缘各是一条圆弧;边宽不一时内外半径不同
outline 跟随 沿圆角轮廓描边(CSS UI 4 §3.1),不占布局;常见的一圈间隙来自 outline-offset,该属性初始值为 0
子内容 默认不裁 overflow: hidden / clip / auto 才被圆角裁切
命中区域 跟随 pointer events 裁到弯曲后的边框边缘,角外余料不可点
布局区域 不变 仍是方形,圆角不参与布局计算

border-radius 能画的弧本质都是圆或椭圆。corner-shape 一页展示它如何在同一个半径上换掉曲线类型,把圆弧推广成 squircle、bevel、scoop、notch 的超椭圆家族。

5 · 参考文献

  1. Bos, B., Lilley, C., Çelik, T., & Atkins, T. (Eds.). CSS Backgrounds and Borders Module Level 3, §4.3 Corner Clipping & §4.5 Overlapping Curves. W3C.
  2. Atkins, T., & Rivoal, F. (Eds.). CSS Basic User Interface Module Level 4, §3.1 Outlines. W3C.