CSS 边框动画

了解在 CSS 中为边框添加动画效果的几种方式

设置边框

您可以通过以下几种方法设置元素边框:borderoutlinebox-shadow。正如 Stephanie Eckles 的 3 种 CSS 添加元素边框的方法中所详述的,每种方法都有自己的优缺点,尤其是在为边框添加动画效果时。不使用适当 CSS border 的主要原因是出于动画目的。

使用 outline-offset 制作边框动画(作者:Kevin J。鲍威尔

最近吸引我的一篇文章是《神奇的 CSS 边框动画》,作者 Coco 在其中探索了更多选项。通过使用 ::before::after 注入生成的内容,他们会创建虚假边框,然后添加动画效果。

我最引人注目的是文章中使用的辅助性动画可视化。它们可以真正帮助说明实现预期效果需要采取哪些措施。

使用 Coco 生成的内容制作 Border Animations

白色层和彩色线条都是生成的内容。通过淡入和淡出白色层,您可以清楚地了解它们的堆叠方式以及动画的运行方式。

保留框模型

使用生成内容来模仿边框的一个缺点是,最终会导致一个损坏的框模型:内容现在可以遮盖人造边框,因为其下方会绘制“边框”。为了缓解此问题,您必须应用所需的 border-width 作为 padding

为了拥有真正的边框,并保留框模型的工作原理,您可以使用多种背景,然后将它们拉伸到边框区域。

基础知识

我们先创建虚线边框并添加多个背景。

/* Size of the border */
--border-size: 0.5rem;

/* Create a dotted border */
border: var(--border-size) dotted lime;

/* Create two background layers:
   1. A white semi-transparent
   2. A layer with the colored boxes
 */
background-image:
  linear-gradient(to right, rgb(255 255 255 / 0.5), rgb(255 255 255 / 0.5)),

  conic-gradient(
    from 45deg,
    #d53e33 0deg 90deg,
    #fbb300 90deg 180deg,
    #377af5 180deg 270deg,
    #399953 270deg 360deg
  )
;

使用 background-origin 调整背景大小

如您所见,此处的背景发生了一些有趣的变化:它们绘制到边框中,但 conic-gradient 似乎全部错误。这实际上是预期行为:默认情况下,背景图片不会绘制到边框中,因为其来源是元素的 padding-box。毕竟,为了创建边框,设置的背景图片会在边框本身中重复,从而产生奇怪的视觉效果。

要解决此问题,您需要拉伸背景,使其也占据边框的大小。您可以通过拉伸和调整背景来手动执行此操作,但最好使用 background-origin 属性根据 border-box 调整背景大小。

浏览器支持

  • 1
  • 12
  • 4
  • 3

来源

错误做法
/* Manually add or offset the size of the border where needed */
background-position: calc(var(--border-size) * -1) calc(var(--border-size) * -1);
background-size: calc(var(--border-size) * 2 + 100%) calc(var(--border-size) * 2 + 100%);
正确做法
background-origin: border-box;

此次添加让一切都变得更好了:

使用 background-clip 缩小白色背景图层

由于背景现在占据了所有空间,半透明图层需要再次缩小。您无需再次修改 background-size,有一种更简单的方法可以做到这一点:使用 background-clip 并将其设置为 padding-box。这样,系统便不会再在边框区域下方绘制背景。

浏览器支持

  • 1
  • 12
  • 4
  • 5

来源

background-clip:
  padding-box, /* Clip white semi-transparent to the padding-box */
  border-box /* Clip colored boxes to the border-box (default) */
;

最后,将边框设为 transparent,以实现完整的效果。

border: 0.3rem dotted transparent;

动画

如需恢复边框的动画,您可以操纵 conic-gradient 的起始角度。

--angle: 0deg;
conic-gradient(
  from var(--angle),
  #d53e33 0deg 90deg,
  #fbb300 90deg 180deg,
  #377af5 180deg 270deg,
  #399953 270deg 360deg
);

得益于 @property,支持在浏览器上实现上述操作可以轻而易举:

浏览器支持

  • 85
  • 85
  • 16.4

来源

@property --angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

@keyframes rotate {
  to {
    --angle: 360deg;
  }
}

总体而言,代码将如下所示:

奖励内容:border-image

之前介绍的渐变边框方法是使用 CSS border-image

浏览器支持

  • 16
  • 12
  • 15
  • 6

来源

它允许简化代码,因为您无需处理重叠的背景。可以用与之前相同的方式应用动画。

/* Create a border */
border: 0.5rem solid transparent;

/* Paint an image in the border */
border-image:
  conic-gradient(
    from var(--angle),
    #d53e33 0deg 90deg,
    #fbb300 90deg 180deg,
    #377af5 180deg 270deg,
    #399953 270deg 360deg
  ) 1
;

但是,您会发现有些地方已不再适合此方法:

  • border-image 不遵循 border-radius;它将始终为矩形。
  • border-image-slice 设置为填充时,border-image 不会绘制在已设置的 background 下方,而是绘制在顶部。如果您希望背景是半透明的,这可能会带来麻烦。

总结

在 CSS 中,为边框添加动画效果的方式多种多样。根据使用场景,您可能会选择其中一种。