CSS 边框动画

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

您可以使用以下几种方法为元素设置边框:borderoutlinebox-shadow。正如 Stephanie Eckles 在 The 3 CSS Methods for Adding Element Borders 中详述的那样,每种方法都有其优点和缺点,尤其是在为边框添加动画时。不使用适当的 CSS border 的主要原因是出于动画目的。

使用 outline-offset 的边框动画(作者:Kevin J. Powell

最近,我注意到了一篇文章,名为 Fantastic CSS border animation(出色的 CSS 边框动画),作者 Coco 在其中探索了更多选项。通过使用 ::before::after 注入生成的内容,他们创建了一个虚拟边框,然后对其进行动画处理。

我最欣赏的是文章中使用的辅助动画可视化图表。它们有助于说明为实现预期效果而采取的具体措施。

使用 Coco 生成的内容的边框动画

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

保留盒模型

使用生成的内容来模拟边框的缺点是,最终会导致盒模型损坏:由于所述“边框”是在下方绘制,因此内容现在可能会遮盖虚拟边框。如需缓解此问题,您必须将所需的 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 调整背景大小。

浏览器支持

  • Chrome:1.
  • Edge:12.
  • Firefox:4.
  • Safari: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-clip 并将其设置为 padding-box,这样就不必再次调整 background-size。这样,系统就不会再在边框区域下方绘制背景。

浏览器支持

  • Chrome:1.
  • Edge:12.
  • Firefox:4.
  • Safari: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,在支持它的浏览器中,这变得轻而易举:

浏览器支持

  • Chrome:85.
  • Edge:85。
  • Firefox:128.
  • Safari:16.4。

来源

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

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

将所有代码合并后,代码如下所示:

奖励内容:border-image

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

浏览器支持

  • Chrome:16.
  • Edge:12.
  • Firefox:15.
  • Safari: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 设置为 fill 时,border-image 不会绘制在设置的 background 下方,而是在顶部。如果您希望背景是半透明的,这可能会带来麻烦。

总结

在 CSS 中为边框添加动画效果的方法有很多。根据用例,您可以选择其中一种。