在平时的开发过程中,大部分时间,我们对 border
的设置,都只是围绕border-width
、border-style
和 border-color
这三个属性。但是突然有一天,公司的 UI 设计突然给你设计了一个不一样的 border
,像下面这样的:
这种情况一般出现在做大屏页面时,为了追求酷炫的效果,会给一些弹框加上统一的边框。这时前面说的那三个属性就无法做出这种效果。
当然,如果直接把图片设置成 background
也可以,但是如果有多个尺寸的弹框,使用这种方法会让图片发生形变。
还好,CSS 中还有另一种设置 border
的方式—— border-image
,它允许在元素的边框上绘制图像。
border-image
它跟 background
一样,也是多个属性的简写方式。
border-image-source: none;
border-image-slice: 100%;
border-image-width: 1;
border-image-outset: 0;
border-image-repeat: stretch;
border-image-source
用来设置图片地址;border-image-slice
用来设置如何切割图片,让切割后的图片,分别对应到不同位置的 border 上;border-image-width
用来设置边框图片的显示宽度;border-image-outset
用来设置边框图像可超出边框盒的大小;border-image-repeat
用来定义图片如何填充边框。
对于这些属性的详细解释,大家可以直接查看 MDN 的文档。
接下来我们就使用 UI 提供的图片,来设置我们的弹框的边框图片:
border-image-source: url('./modal-bg.png');
border-image-slice: 150 200 fill;
border-image-width: 150px 200px;
border-image-repeat: stretch;
border-image-source
没有太多需要解释的,重点来解释 border-image-slice
,它是设置 border-image
的关键。
在切割图片时,会将图片分割为 9 个区域:四个角、四个边以及中心区域。
上图说明了每个区域的位置。
- 区域 1-4 为角区域(corner region)。每一个都被用于组成最终边框图像的四个角。
- 区域 5-8 边区域(edge region)。在最终的边框图像中重复、缩放或修改它们以匹配元素的大小。
- 区域 9 为中心区域(middle region)。它在默认情况下会被丢弃,但如果设置了关键字
fill
,则会将其用作元素的背景图像。
border-image-slice
属性可以用四个指定的 数字或百分比 值来表示每一个图像切片的位置。负数是无效的,而大于其相应的最大尺寸的值则会被限制为 100%。
设置时类似于设置 margin
、padding
的规则:
- 当只使用 1 个值时,创建的(上下左右)四个切片将具有相同的宽度/高度,相当于设置了四个一样的值。
- 当只使用 2 个值时,第一个值表示垂直方向的两个切片的高度(即 top 与 bottom),第二个值表示水平方向两侧切片的宽度(即 left 和 right)。
- 当指定了三个位置(3 个值)时,第一个值表示顶部切片的高度(即 top),第二个值表示水平方向两侧切片的宽度(即 left 和 right),第三个值则表示底部切片的高度(即 buttom)。
- 当指定了四个位置(4 个值)时,这四个值则分别对应 top、right、buttom、left(上、右、下、左)四个切片的宽度/高度。
可选值 fill
可放在上面声明的值的末尾。
我们设置的 border-image-slice: 150 200 fill;
切割情况如下图:
1、2、3、4 分别会用于 div 的四个角;
5、6、7、8分别用在 div 上对应的四个边区域,当它们不能填满 div 对应的区域时,由于我们设置了 border-image-repeat: stretch;
,这四块图片会被拉伸以填充 div 上对应的区域。
9 这块图片会被用做 div 中间的背景图片,因为我们设置了 fill
。
border-image-width
设置的值与 border-image-slice
一致,这样可以保证图片不变形。也可以直接设置为 auto
,表示与 border-image-slice
保持一致。
特别需要注意的是,如果我们设置的值是一个数字,后面没有单位,它表示 border-image-width
的宽度,是 border-width
的相应倍数,不能为负。
渐变色 border
border-image-source
可以设置图片,也可以设置渐变色,如下代码:
.border-gradient {
width: 200px;
height: 100%;
border-image: linear-gradient(180deg, #6638F0 20%, #F78AE0 100%) 1/1;
border-style: solid;
border-width: 10px;
}
效果
这里需要注意,这种情况下必须设置 border-style
属性。
设置渐变色 border,在设置 border-style
时,如果要使用 border
这个简写属性,需要注意它与 border-image
的书写顺序,border
在前, border-image
在后。如果是 border
在后,它会把 border-image
的属性重置成默认值。
和所有的简写属性一样,如果有缺省值会被设置成对应属性的初始值。同时需要注意设置border对border-image属性的影响,虽然border属性不能设置这个属性,但会把该属性重置为初始值none。这使得我们可以用border属性去重置整个样式表中的border设置。因为W3C计划在未来的标准中保留该属性,因此建议使用该属性重置边框设定。
从 chrome 中看,border-image
的相关属性都被设置成了 initial
。
.border-gradient {
width: 200px;
height: 200px;
border-image: linear-gradient(180deg, #6638F0 20%, #F78AE0 100%) 1/1;
/* border 属性写在 border-image 之后 */
border: 10px solid #000;
}
border-radius 无效问题
当我们使用 border-image
的方式实现了渐变色 border 之后,如果再去设置 border-radius
,这个时候圆角并不会作用于渐变色的 border 上。
如果想要实现有圆角的 border,可以换种方式,使用两个 div,外面的 div 设置渐变色背景,然后再设置 padding,这样也能达到 border 的效果。