CSSで虹色に遷移するグラデーションのアニメーション

## 前置き

### （現状）linear-gradientは色をアニメーションできない。

背景色に線形グラデーションを敷きたい時によく使われる、
[linear-gradient](https://developer.mozilla.org/ja/docs/Web/CSS/gradient/linear-gradient)（および[repeating-linear-gradient](https://developer.mozilla.org/ja/docs/Web/CSS/gradient/repeating-linear-gradient)）。
アニメーションで色を徐々に遷移させたいところですが、
グラデーション関数に対して直接アニメーションをかけることはできません。

[CSSカスタムプロパティ](https://developer.mozilla.org/ja/docs/Web/CSS/--*)（通称CSS変数）と[@property](https://developer.mozilla.org/ja/docs/Web/CSS/@property)を使用すると
関数中に内包される色や角度に対してアニメーションを設定できるのですが、
肝心の@&#xFFF0;propertyの[ブラウザ対応状況がいまいち](https://caniuse.com/mdn-css_at-rules_property)なため現状では使えません。

そこで現状でできる、グラデーションのアニメーション方法について書いていきます。

## とりあえず虹色のグラデーションを作る

```css
body {
    width: 100%;
    min-height: 100vh;	
    background-image: repeating-linear-gradient(
        to bottom right,
        hsl(0deg, 80%, 50%),
        hsl(60deg, 80%, 50%),
        hsl(120deg, 80%, 50%),
        hsl(180deg, 80%, 50%),
        hsl(240deg, 80%, 50%),
        hsl(300deg, 80%, 50%),
        hsl(360deg, 80%, 50%) 50%
    );
}
```

![名称未設定-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135161/2dc38358-287e-681e-bd56-663b00c4602b.jpeg)

虹色（七色というより六色ですが）のグラデーションを対角線に沿って、
0%から50%の範囲で`repeating-linear-gradient`を使って配置します。
虹色の発色を思い通りにコントロールするときは`hsl()`が便利です。
開始点の色相は何色でも構いませんがそこから60degごとに色を置けば綺麗な発色になるはずです。
最後の色は最初と同じ色になるようにします（つまり360度分）。

最後の`50%`だけ指定しておけば、0の時と途中の経由点については勝手に中間点を計算してくれます。
50%までの指定とすることで、50%〜100%は同じグラデーションが描かれます。
またグラデーションの角度については角度指定ではなく`to bottom right`のようなキーワード指定を使います。

## 虹色を超拡大して引き伸ばす

```css
body {
    width: 100%;
    min-height: 100vh;	
    background-image: repeating-linear-gradient(
        to bottom right,
        hsl(0deg, 80%, 50%),
        hsl(60deg, 80%, 50%),
        hsl(120deg, 80%, 50%),
        hsl(180deg, 80%, 50%),
        hsl(240deg, 80%, 50%),
        hsl(300deg, 80%, 50%),
        hsl(360deg, 80%, 50%) 50%
    );
    background-size: 1000% 1000%;
}
```

![colo4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135161/ad1d51b0-e576-3cf5-d7e1-db7ecdd02c5d.jpeg)

次に`background-size`を大胆に縦横ともに`1000%`くらいの値を指定します。
これで虹色が引き伸ばされ画面上では2色〜3色分くらいの色のグラデーションが見えるはずです。


## background-positionにアニメーションを指定する

```css
body {
    width: 100%;
    min-height: 100vh;	
    background-image: repeating-linear-gradient(
        to bottom right,
        hsl(0deg, 80%, 50%),
        hsl(60deg, 80%, 50%),
        hsl(120deg, 80%, 50%),
        hsl(180deg, 80%, 50%),
        hsl(240deg, 80%, 50%),
        hsl(300deg, 80%, 50%),
        hsl(360deg, 80%, 50%) 50%
    );
    background-size: 1000% 1000%;
    animation: colorRotation 240s linear 0s infinite;
}

@keyframes colorRotation {
	from {
		background-position: 0 0;
	}
	to {
		background-position: 500% 500%;
	}
}
```

あとは`background-position`にアニメーションを指定するだけです。
アニメーションを間隔は0%から`background-size`で指定したサイズの半分までにします。
これで切れ目なくグラデーションがループされます。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="NWMRjXz" data-user="ichimonzi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ichimonzi/pen/NWMRjXz">
  Untitled</a> by ichimonzi (<a href="https://codepen.io/ichimonzi">@ichimonzi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 一色を固定してもう一色だけアニメーションする場合

グラデーション関数に対して直接アニメーションをかけることはできませんが、
`background-color`に関してはアニメーションできます。
そこで透明色（`transparent`）と固定色の間でグラデーションを作り、
アニメーションする色は`background-color`を使うことによって擬似的に
グラーデーションのアニメーションをすることができます。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="bGMwWLM" data-user="ichimonzi" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ichimonzi/pen/bGMwWLM">
  Untitled</a> by ichimonzi (<a href="https://codepen.io/ichimonzi">@ichimonzi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## おまけ

![col4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135161/5a72143d-f8c1-f892-75ae-0e1422368c43.jpeg)

@&#xFFF0;propertyが全面サポートされるようになれば、
こんなサイケデリックパターンもグリグリアニメーションできるようになります。
実際見たい方は[こちら](https://codepen.io/ichimonzi/pen/OJZXaJa)。
※（現状PC Chrome、Chrome for Android、Edgeなどでしか動きません）