在项目中需要实现一个圆角渐变边框效果。

我的第一反应是使用 border-radius 对 border-image。然而实践后发现 border-radius 对 border-image 不生效效果是这样的:

给 div 设置了 border-radius,但边框仍然是直角。
为什么 border-radius 对 border-image 失效?
两者的工作层级不同:
border-radius作用在 div 元素上,它控制的是整个 div 轮廓的圆角。border-image绘制边框,是独立于 div 之外的,是脱离于 div 的。
所以,看到的效果就是边框依然是直角,而 div 是圆角。
实现方案
主要通过两点来实现:
- 创建一个稍大于主元素的伪元素,并设置渐变背景。
- 使用CSS遮罩"挖空"中间部分,只留下边框区域。
代码如下:
css
.gradient-border-box {
width: 100px;
height: 100px;
border-radius: 6px;
position: relative;
}
.gradient-border-box::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 6px; /* 和主元素相同的圆角 */
padding: 1px; /* 边框宽度 */
/* 渐变效果 */
background: linear-gradient(360deg,
rgba(96, 161, 250, 0.5),
rgba(96, 161, 250, 1));
/* CSS遮罩 */
mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
mask-composite: exclude;
}
方案解析
-
主元素: 负责内容区域和圆角,只设置
border-radius。 -
伪元素: 负责绘制渐变边框,它的位置与大小覆盖主元素,通过:
background绘制渐变padding控制边框宽度mask挖空中间区域
伪元素中的遮罩详解
css
mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
mask-composite: exclude;
-
-webkit-mask: 这行代码创建了两个完全相同的白色矩形遮罩,第一个仅作用于内容区域(content-box);第二个作用域整个元素区域(border-box)。第一个
linear-gradient(#fff 0 0)创建一个纯白色矩形(线性渐变,从0%到0%);content-box指定遮罩的参考框,作用域元素的内容区域(不包括padding、border);第二个
linear-gradient(#fff 0 0)创建了一个白色矩形,默认是 border-box(包括内容+padding+border)。 -
mask-composite:exclude: 控制多个遮罩如何组合 ,exclude代表异或操作。结合遮罩解释就是: 边框区域 = border-box(整个区域) - content-box(中心区域)