CSS 邊框動畫

探討在 CSS 中為邊框製作動畫的多種方法

以下提供幾種設定元素框線的方法:borderoutlinebox-shadow。如 Stephanie Eckles 在 CSS 新增元素邊框的 3 種方法一文中所述,每種方法都有各自的優缺點,尤其是在邊框動畫方面。不使用適當的 CSS border 的主要原因是為了製作動畫。

使用 outline-offset 製作邊框動畫outline-offset (作者:凱文 J.Powell

我最近看到一篇文章「Fantastic CSS border animation」,作者 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.
  • 邊緣: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.
  • 邊緣: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 設為填滿時,border-image 並未在設定 background 下方繪製,而是在頂端繪製。如果您想將背景設為半透明,就可能會遇到問題。

結語

在 CSS 中,邊框的動畫方式有多種可能。視用途而定,您可能會偏向使用其中一種。