border-image (1)

593 阅读6分钟

border-image

CSS属性border-image是一项有趣且强大的属性,允许我们在元素的边框上绘制图像,这使得创建复杂外观的组件变得更加简单。该属性是border-image-sourceborder-image-sliceborder-image-widthborder-image-outsetborder-image-repeat5个属性的简写形式,因此,该属性的值可以指定前面列举的5个属性中一个或多个。本篇文章主就border-image的介绍、常规用法及其第一个属性border-image-source应用的简单举例

属性值

border-image-source:图片源

border-image-slice:对图片源进行区域切片的尺寸,最多可以指定4个值,该属性还可以指定一个关键字fill,将图片源内部区域缩放后填充于border-image元素内部区域,填充层级会比background高 ,描述方式与margin类似,值类型为numberpercentage

border-image-width:图片边框的宽度,最多可以指定4个值,描述方式与margin类似,值类型为length-percentagenumberauto

border-image-outset:图片边框到延伸出边框的距离,最多可以指定4个值,描述方式与margin类似,值类型为lengthnumber

border-image-repeat:定义图片源的边缘区域适应border-image的尺寸的方式,最多可以指定两个值

  1. 因为border-image-sliceborder-image-widthborder-image-outset这三个属性均能指定多个值,因此指定这三个属性的值时应采用/对其进行分割
  2. 因为border-image实际上是上面五种属性的简写,当有需求时,分别给属性指定值也是完全没问题的

用法介绍

常规用法

正如文章开头所说,border-image允许我们在元素边框上绘制图像,想象一下,如果我们有一些类似于下图target-element的图片需要添加image-source这样的边框,做成final-presentation这样的效果,一般的做法可能是直接启动Photoshop进行操作了[没错,我们前端开发者就是这么的全能,哈哈],这里我们用上border-image属性将会很轻松的搞定这个需求,我们只需要给目标元素添加border-image:slice / width / outset即可,示例如下: 常规应用示例1.png

<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;
}

常规用法 (codepen.io)

设置border-image之前必须设置border,否则border-image不会应用

介绍完border-image的常规用法之后,让我们来看看这个属性有哪些特殊的用法。

border-image-source

前面说到了border-image-source是图片源,而CSS中有一类特殊的"值"它们也是"图片",可能已经有大佬已经猜到了,没错,它就是gradient这类值,让我们看看这两个的碰撞能创造些什么意外的惊喜。

border-image-source与conic-gradient的碰撞

流光边框效果,一种常规的做法是准备一个背景元素(伪元素也行),然后对其设置旋转动画,如同下图所示: generalStreamerBorder.gif

<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);
  }
}

常规流光边框 (codepen.io)

  1. 这类动画用CSS实现方式很多,但基本原理差不多,都是利用一个元素生成背景,然后再给这个背景施加旋转动画,深究其他实现方式脱离本文主题了
  2. 本文案例为了不影响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-gradientradial-gradientrepeating-linear-gradientrepeating-conic-gradient以及repeating-radial-gradient值(函数)与border-image碰撞会有怎么样的火花就交给小伙伴们去探索了,探索完之后记得回来分享哦~

border-image-slice、border-image-width、border-image-outset的用法

这里之所以会将这三个属性放在一起讲是因为border-image-widthborder-image-outset是基于border-image-slice的,让我们看看这三个属性有啥神奇的地方吧。下面两节后面有精力再更新算了,写不动了~

实现水印

实现交互

结语

不知不觉文章就行至尾声了,这是本人在掘金的第二篇文章,虽然我已经竭尽全力确保文章表达内容准确,但无奈新手起步、经验尚浅,文章如若有表述欠妥之处还望留言告知。另外,个人认为随着CSS的发展,CSS能为我们呈现的精彩往往不在于其本身,更多的令人惊叹之处通常在书写者的脑海,脑洞有多大,页面就有多炫酷,小伙伴们还有哪些关于border-image属性的用法呢?欢迎在评论区一起分享、探讨。(完结了,我要饭去了\^.^/~