border-image
CSS属性border-image是一项有趣且强大的属性,允许我们在元素的边框上绘制图像,这使得创建复杂外观的组件变得更加简单。该属性是border-image-source、border-image-slice、border-image-width、border-image-outset、border-image-repeat5个属性的简写形式,因此,该属性的值可以指定前面列举的5个属性中一个或多个。本篇文章主就border-image的介绍、常规用法及其第一个属性border-image-source应用的简单举例
属性值
border-image-source:图片源
border-image-slice:对图片源进行区域切片的尺寸,最多可以指定4个值,该属性还可以指定一个关键字fill,将图片源内部区域缩放后填充于border-image元素内部区域,填充层级会比background高 ,描述方式与margin类似,值类型为number和percentage
border-image-width:图片边框的宽度,最多可以指定4个值,描述方式与margin类似,值类型为length-percentage、number和auto
border-image-outset:图片边框到延伸出边框的距离,最多可以指定4个值,描述方式与margin类似,值类型为length和number
border-image-repeat:定义图片源的边缘区域适应border-image的尺寸的方式,最多可以指定两个值
- 因为
border-image-slice、border-image-width、border-image-outset这三个属性均能指定多个值,因此指定这三个属性的值时应采用/对其进行分割- 因为
border-image实际上是上面五种属性的简写,当有需求时,分别给属性指定值也是完全没问题的
用法介绍
常规用法
正如文章开头所说,border-image允许我们在元素边框上绘制图像,想象一下,如果我们有一些类似于下图target-element的图片需要添加image-source这样的边框,做成final-presentation这样的效果,一般的做法可能是直接启动Photoshop进行操作了[没错,我们前端开发者就是这么的全能,哈哈],这里我们用上border-image属性将会很轻松的搞定这个需求,我们只需要给目标元素添加border-image:slice / width / outset即可,示例如下:
<div class="final-presentation"></div>
body {
display: flex;
margin: 0 auto;
width: 90vw;
height: 100vh;
justify-content: center;
align-items: center;
}
div.final-presentation {
width: 256px;
height: 256px;
background: center url("https://picsum.photos/id/684/901/901");
/*border is required*/
border: 1px solid red;
/*border-image:source slice / width / outset*/
border-image: url(./img/border-image-source2.png) 25 / 25 / 25;
}
设置
border-image之前必须设置border,否则border-image不会应用
介绍完border-image的常规用法之后,让我们来看看这个属性有哪些特殊的用法。
border-image-source
前面说到了border-image-source是图片源,而CSS中有一类特殊的"值"它们也是"图片",可能已经有大佬已经猜到了,没错,它就是gradient这类值,让我们看看这两个的碰撞能创造些什么意外的惊喜。
border-image-source与conic-gradient的碰撞
流光边框效果,一种常规的做法是准备一个背景元素(伪元素也行),然后对其设置旋转动画,如同下图所示:
<div>流光</div>
body {
margin: auto;
width: 90%;
height: 80vh;
display: flex;
justify-content: center;
align-items: center;
}
div {
padding: 2px;
width: 200px;
height: 50px;
text-align: center;
font-size: 20px;
line-height: 50px;
background-color:#ffffff;
background-clip:content-box;
position: relative;
overflow: hidden;
}
div::before {
content: "";
background: conic-gradient(
from var(--selfRotation, 0deg),
#21d4fd,
#0000 30deg 120deg,
#b721ff 150deg 180deg,
#0000 210deg 300deg,
#21d4fd 330deg
);
position: absolute;
inset: -999px;
z-index: -1;
}
div:hover::before {
animation: streamerBorder 2s linear infinite;
}
@keyframes streamerBorder {
to {
transform: rotateZ(360deg);
}
}
- 这类动画用CSS实现方式很多,但基本原理差不多,都是利用一个元素生成背景,然后再给这个背景施加旋转动画,深究其他实现方式脱离本文主题了
- 本文案例为了不影响HTML结构采用了伪元素作为背景,这样确保了HTML结构的单纯性
上面我们简单的实现了一个流光边框效果,那么如果利用border-image又该如何实现呢?让我们看看下面的案例:
<div>流光</div>
@property --stramerBorderAngle {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
body {
margin: auto;
width: 90%;
height: 80vh;
display: flex;
justify-content: center;
align-items: center;
}
div {
width: 200px;
height: 50px;
text-align: center;
font-size: 20px;
line-height: 50px;
position: relative;
border: 2px solid red;
border-image: conic-gradient(
from var(--stramerBorderAngle, 0deg),
#21d4fd,
#0000 30deg 120deg,
#b721ff 150deg 180deg,
#0000 210deg 300deg,
#21d4fd 330deg
)
1%;
}
div:hover {
animation: streamerBorder 2s linear infinite;
}
@keyframes streamerBorder {
to {
--stramerBorderAngle: 360deg;
}
}
应用border-image的流光边框 (codepen.io)
可以发现采用border-image制作的流光边框和常规方法制作的流光边框一模一样,但后者的CSS书写量少了,操作的对象少了,也更加直观了。
这里利用了CSS的@property规则,这是CSS HoudiniAPI的一部分,想了解更多的小伙伴可以去查看@property文档 | MDN (mozilla.org)
border-image实现的流光边框是有缺陷的,ta没法把边框做出倒角的形状😭
限于文章篇幅,这里只拿conic-gradient来进行演示,其余的如linear-gradient、radial-gradient、repeating-linear-gradient、repeating-conic-gradient以及repeating-radial-gradient值(函数)与border-image碰撞会有怎么样的火花就交给小伙伴们去探索了,探索完之后记得回来分享哦~
border-image-slice、border-image-width、border-image-outset的用法
这里之所以会将这三个属性放在一起讲是因为border-image-width、border-image-outset是基于border-image-slice的,让我们看看这三个属性有啥神奇的地方吧。下面两节后面有精力再更新算了,写不动了~
实现水印
实现交互
结语
不知不觉文章就行至尾声了,这是本人在掘金的第二篇文章,虽然我已经竭尽全力确保文章表达内容准确,但无奈新手起步、经验尚浅,文章如若有表述欠妥之处还望留言告知。另外,个人认为随着CSS的发展,CSS能为我们呈现的精彩往往不在于其本身,更多的令人惊叹之处通常在书写者的脑海,脑洞有多大,页面就有多炫酷,小伙伴们还有哪些关于border-image属性的用法呢?欢迎在评论区一起分享、探讨。(完结了,我要饭去了\^.^/~