CSS 枠線アニメーション

CSS で枠線をアニメーション化する方法をいくつか見ていきます。

枠線の設定

要素に枠線を設定するには、borderoutlinebox-shadow のメソッドを使用できます。Stephanie Eckles による The 3 CSS Methods for Additional Element Borders で詳しく説明されているように、それぞれの方法には独自の長所と短所があります。特に、境界をアニメーション化する場合です。適切な CSS border を使用しない主な理由は、アニメーションの目的です。

Border Animations using outline-offset(Kevin J. Powell

最近の記事で Fantastic CSS 枠線アニメーションに目を引かれました。著者の Coco は他の選択肢についても紹介しています。::before::after を使用して生成コンテンツを挿入すると、疑似枠線が作成されてアニメーション化されます。

特に印象に残ったのは、記事の中でアニメーションによるビジュアリゼーションが使用されていることです。目的とする効果を得るために何を行っているかを正確に説明するのに役立ちます。

Coco で生成されたコンテンツを使用したボーダー アニメーション

白いレイヤと色付きの線の両方が、生成されたコンテンツです。白いレイヤをフェードイン / アウトすることで、それらがどのように積み重ねられ、アニメーションの仕組みが明確になります。

ボックスモデルの保持

生成コンテンツを使用して境界線を模倣することのデメリットは、ボックスモデルが壊れることです。「境界線」が下にペイントされるため、コンテンツによって偽の境界線が見えにくくなります。軽減するには、目的の border-widthpadding として適用する必要があります。

真の枠線を作成し、ボックスモデルの動作を維持するには、複数の背景を使用して境界領域に引き伸ばします。

基本情報

まず、点線の枠線を作成し、複数の背景を追加しましょう。

/* 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;

この 1 つの追加で、見た目が大幅に改善されました。

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-imageborder-radius の形ではなく、常に長方形です。
  • border-image-slice を塗りつぶすように設定すると、border-image はセット background の下ではなく上に描画されます。背景を半透明にしたい場合には、この方法が問題になることがあります。

まとめ

CSS では、さまざまな方法で枠線をアニメーション化できます。ユースケースによっては、どちらか一方を利用することもあります。