渐变描边:让渐变沿着圆角流动
前三页讲的是角本身,这一页讲边,而它最难的地方仍是圆角。原生 border 只接受纯色,想给边框上渐变,第一直觉是 border-image:它确实能把渐变铺到边框上,却完全无视
border-radius,四角立刻变回直角。于是整套渐变描边技巧本质都在回答同一个问题——怎样让一道渐变严丝合缝地贴着圆角走。
1 · 渐变与圆角的冲突
border-color 只能是纯色,渐变无从谈起。退一步用 border-image: linear-gradient(...),渐变是上去了,但 border-image 把边框区域当成一张九宫格图片来贴,不参与圆角裁剪,所以无论 border-radius 设多大,描边的四角都是直角。
border-image 的直角描边,右为 background-clip 双层法:border-box 层承载渐变、padding-box 层盖住内芯,渐变只在边框环露出并天然跟随圆角。可拖滑块改半径对比两者。
注 · border-image 并非不能用,而是它与 border-radius 互斥。规范里 border-image 一旦生效就替换掉常规边框的绘制,而圆角裁剪只作用于「常规边框 +
背景」这条路径,管不到贴上去的图。要同时拿到渐变与圆角,就得把渐变放进背景或遮罩,让它走那条会被圆角裁剪的绘制路径。
2 · 两种贴着圆角的静态做法
背景双层法把 border 设成透明,背景叠两层:padding-box 那层是纯色内芯、border-box 那层是渐变,渐变只在透明边框处露出。遮罩法用一个 ::before 铺满渐变,再用两层 mask 做
exclude,只留下边框环。遮罩法更通用,任意渐变与形状都对;双层法更简短,但只适合内芯纯色的场景,内芯要透出底下内容时得用遮罩法。
建议 · 遮罩法的关键是 mask-composite: exclude:一层 mask 裁到 content-box(内芯区域)、一层覆盖整盒,exclude 取「整盒减去内芯」,得到一圈边框环。有一处容易记反的兼容性事实——标准 mask-composite 与 exclude 在 Safari
15.4(2022-03)就已支持,反倒是 Chrome 到 120(2023-12)才跟上,Firefox 最早(53,2017-04)。_shared.css 仍保留 -webkit-mask 与 -webkit-mask-composite: xor 两行,是为兼容 Safari 15.3 及更早;注意
-webkit-mask-composite 是非标准属性,用的是另一套关键字(xor 而非 exclude),并不是「Safari 版的写法」(兼容性据 MDN BCD,核对于 2026-08)。
3 · 用 @property 让描边旋转
把双层法里的渐变换成 conic-gradient(from var(--angle), …),再让 --angle 从 0deg 转到 360deg,描边就沿圆角流动。关键在 @property:裸自定义属性是字符串,动画引擎不知道怎么补间;用 @property 把 --angle 注册成
<angle> 类型后,它才能像普通角度值一样被 @keyframes 平滑插值。
<angle> 的 --angle 驱动 conic 渐变绕圆角轮廓旋转。可拖滑块改转速或暂停。
注 · 未注册的自定义属性,其值在 CSS 看来只是一段不透明文本,@keyframes 无法在两段文本之间取中间值,动画会在 0deg 与 360deg 之间跳变或干脆不动。@property 的
syntax: "<angle>" 给了它类型,浏览器据此知道如何插值,这也是 @property 让「动画任意自定义属性」成为可能的根本。_shared.css 里已按 prefers-reduced-motion: reduce 停转。
4 · 无 @property 时的降级
@property 出现之前,旋转渐变靠的是另一招,且处处可用:外层 overflow: hidden 加 border-radius 裁出圆角,内部塞一张远大于盒子的渐变层,用
transform: rotate 整张转,再叠一层内芯盖住中间,只留下一圈边框。转的是元素而非渐变的角度,因此不需要可动画的自定义属性。不支持 @property 的浏览器里,上一节的 conic 渐变会停在起始角不动,本节就是它的退路。
警示 · 降级方案的代价是多两层 DOM,且渐变层必须做得足够大。盒子是长方形时,旋转中的方形渐变层要在任意角度都盖满四角,边长得取到对角线以上——_shared.css 用的是 260%,留了足够余量。它胜在只依赖 transform: rotate 与
overflow: hidden 的圆角裁剪,也就是border-radius 一页讲过的能力。
从切图到border-radius再到corner-shape,前三页让角一步步从图片资产变成声明式样式。本页是边的同一个故事:渐变描边的全部工程,都是为了让一道颜色沿着那条圆角轮廓流动。
5 · 参考文献
- MDN Web Docs.
mask-composite(含exclude与非标准-webkit-mask-composite的关键字差异). Mozilla. - MDN Web Docs.
@property(syntax描述符与自定义属性的插值). Mozilla. - Bos, B., et al. (Eds.). CSS Backgrounds and Borders Module Level 3, §6 Border Images. W3C.