CSS 枠線アニメーション

CSS で枠線をアニメーション化するいくつかの方法

枠線の設定

要素に枠線を設定するには、border、outline、box-shadow のいくつかの方法があります。Stephanie Eckles 氏の The 3 CSS Methods for Adding Element Borders で詳しく説明されているように、それぞれのアプローチには長所と短所があります。特に、枠線のアニメーション化に関しては、その傾向が顕著です。適切な CSS border を使用しない主な理由は、アニメーションを目的としているためです。

outline-offset を使用した枠線アニメーション(Kevin J. Powell

最近、素晴らしい 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 に対して背景のサイズを設定することをおすすめします。

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 3.

Source

すべきでないこと
/* 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;

この 1 つの追加により、すべてがはるかに見やすくなります。

background-clip を使用して白い背景レイヤーを縮小する

背景がすべてのスペースを占めるようになったため、半透明のレイヤを再度縮小する必要があります。background-size を再度操作する代わりに、background-clip を使用して padding-box に設定するという簡単な方法があります。これにより、背景が枠線の領域の下に描画されなくなります。

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 5.

Source

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 のおかげで、これをサポートするブラウザでは簡単に実現できます。

Browser Support

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

Source

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

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

すべてを組み合わせると、コードは次のようになります。

ボーナス コンテンツ: border-image

グラデーションの枠線を描画する以前に説明したアプローチは、CSS border-image を使用することです。

Browser Support

  • Chrome: 16.
  • Edge: 12.
  • Firefox: 15.
  • Safari: 6.

Source

背景の重複を処理する必要がないため、コードをより簡素化できます。アニメーションは以前と同じ方法で適用できます。

/* 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 で枠線をアニメーション化する方法は多数あります。ユースケースに応じて、どちらか一方に傾く可能性があります。