タイトルの通りなんですが、linear-gradientでグラデをかけたボタンを、transitionでフワッと切り替えたかったんですが、結構ハマってしまったので、備忘を込めてメモです。
まずは答えから
<p><a href="#" class="btn">ボターン</a></p>
.btn {
background-image: linear-gradient(to left, rgba(213, 0, 0, 1), rgba(239, 71, 9, 1));
position: relative;
z-index: 0;
transition: .3s;
}
.btn:after {
content: "";
width: 100%;
height: 100%;
display: block;
position: absolute;
top: 0;
left: 0;
z-index: -1;
background-color: rgba(184, 0, 0, 1);
opacity: 0;
transition: .3s;
}
.btn:hover:after {
opacity: 1;
}
実際に動作しているのはこちらです。
https://codepen.io/anon/pen/wYPvOr#anon-login
ポイントは.btnに指定した z-index: 0;と、.btn:afterに指定した z-index: -1;、 opacity: 0; です。
何をしているの?
ボタンにグラデを指定して、:after要素でホバー後の単色を指定しています。
.btn自体に linear-gradient でグラデをかけています。
この時、position: relative;を指定し、z-index: 0;を指定しています。
このz-index: 0;の値は別になんでもいいのですが、指定していることが重要です。
さらに.btn:after にホバー後の背景色を指定し、z-index: -1;を指定します。これでaタグのテキストと背景の間に:after要素が設置されます。
この時、.btn要素自体にz-indexが指定されていないと、順序が狂ってうまく動かないので注意です。
次に、ホバー後の背景色を指定した:after要素を指定し、z-index: -1;とopacity: 0;を指定しておきます。
あとは、ホバー時に:after要素のopacityを1にしてやれば完成です。
まとめ
そもそもbackground-imageをtransitionの対象に含めることはできないそうです。
https://teratail.com/questions/21917
色々なサイトで紹介されていた方法を試してみたのですが、どうにもうまくいかなくて今回の方法をとりました。
この方法であれば、グラデ→単色、単色→グラデの両パターンいけるので、使い勝手がいいのかなと思います。
同じことでハマってる人がいればぜひ〜。