在项目中需要实现一个圆角渐变边框效果。
我的第一反应是使用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遮罩"挖空"中间部分,只留下边框区域。
代码如下:
.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挖空中间区域
伪元素中的遮罩详解
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(中心区域)