グラデーションボタンをマウスオンでふわっと変える方法【transitionが効かない理由も解説】

公開日
最終更新日
グラデーションボタンの色をマウスオンでふわっと変える

CSSで作ったボタンの色を、マウスオンでふわっと切り替える。単色ボタンならtransitionを指定するだけで簡単に実現できますが、背景をグラデーションにした途端、この効果が効かなくなってしまいます。

結論から言うと、グラデーションボタンをふわっと変化させるには、擬似要素(::before::after)に2つのグラデーションを重ね、opacityを切り替えるという方法を使います。この記事では、単色ボタンの基本から、なぜグラデーションだと効かないのか、そして擬似要素を使った解決法までを、動くデモとあわせて解説します。

単色ボタンのデモ

まずは基本形です。単色の背景色であれば、transitionを指定するだけでマウスオン時にゆっくりと色が変化します。下のボタンにマウスを乗せてみてください。

<div class="btn btn1">
    <a href="">
        BUTTON 1
    </a>
</div>
.btn a {
    position: relative;
    z-index: 0;
    color: #fff;
    width: 400px;
    height: 80px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: bold;
    text-decoration: none;
    border-radius: 10px;
    overflow: hidden;
    transition: 0.5s;
}

.btn1 a {
    background: rgba(0, 119, 255, 1);
}

.btn1 a:hover {
    background: rgba(252, 69, 123, 1);
}

グラデーションボタンだとtransitionが効かない理由

ところが、背景をグラデーションに変えると、同じtransitionを指定しても色がパッと切り替わるだけで、ふわっとした変化になりません。下のボタンで確認できます。

理由は、グラデーションの正体にあります。単色のbackground-colorはアニメーション可能なプロパティですが、linear-gradient()で作るグラデーションはbackground-imageとして扱われます。そしてbackground-imageは、多くのブラウザで滑らかに補間できないプロパティです。そのため、transitionを指定しても中間の状態が描画されず、瞬時に切り替わってしまうわけです。

補足すると、グラデーションの色だけを滑らかに変化させるアニメーションは、CSS単体では基本的に扱えません。単色で十分ならbackground-colorで組むのが最もシンプルですが、グラデーションの質感を保ったままふわっと変化させたい場合は、次に紹介する擬似要素を使う方法が定番の解決策になります。

<div class="btn btn2">
    <a href="">
        BUTTON 2
    </a>
</div>
.btn a {
    position: relative;
    z-index: 0;
    color: #fff;
    width: 400px;
    height: 80px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: bold;
    text-decoration: none;
    border-radius: 10px;
    overflow: hidden;
    transition: 0.5s;
}

.btn2 a {
    background: rgb(0, 119, 255);
    background: linear-gradient(90deg, rgba(0, 119, 255, 1) 0%, rgba(252, 69, 123, 1) 100%);
}

.btn2 a:hover {
    background: rgb(255, 0, 0);
    background: linear-gradient(90deg, rgba(255, 0, 0, 1) 0%, rgba(252, 176, 69, 1) 100%);
}

擬似要素でグラデーションをふわっと変える

そこで発想を変えます。グラデーションそのものをアニメーションさせるのではなく、2枚のグラデーションを重ねて置き、上の1枚をopacityでフェードさせるのです。opacityはアニメーション可能なプロパティなので、これならふわっとした変化を実現できます。下のボタンが完成形です。

仕組みはこうです。::beforeに通常時のグラデーションを、::afterにマウスオン時のグラデーションを設定し、::beforeを手前(z-indexが上)に重ねておきます。通常は手前の::beforeだけが見えている状態です。

そしてマウスオン時に::beforeopacity: 0;で透明にすると、奥に隠れていた::afterのグラデーションが透けて現れます。::before側にだけtransitionを効かせているため、透明になる過程がゆっくり進み、結果としてグラデーションがふわっと切り替わったように見える、というわけです。::afterは常に表示されたままなのでtransitionは不要で、動かすのは手前の::beforeだけ、という点を押さえるとシンプルに実装できます。

<div class="btn btn3">
    <a href="">
        BUTTON 3
    </a>
</div>
.btn a {
  position: relative;
  z-index: 0;
  color: #fff;
  width: 400px;
  height: 80px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-weight: bold;
  text-decoration: none;
  border-radius: 10px;
  overflow: hidden;
  transition: 0.5s;
}

.btn3 a:before {
  content: "";
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: -1;
  left: 0;
  transition: 0.5s;
  background: rgb(0, 119, 255);
  background: linear-gradient(90deg, rgba(0, 119, 255, 1) 0%, rgba(252, 69, 123, 1) 100%);
}

.btn3 a:after {
  content: "";
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: -2;
  left: 0;
  background: rgb(255, 0, 0);
  background: linear-gradient(90deg, rgba(255, 0, 0, 1) 0%, rgba(252, 176, 69, 1) 100%);
}

.btn3 a:hover:before {
  opacity: 0;
}

擬似要素をボタンの背面に敷くため、親要素のaにはposition: relative;overflow: hidden;を指定しておくのがポイントです。角丸(border-radius)からグラデーションがはみ出さず、きれいに収まります。

変化のスピードは::beforetransitionの秒数(この例では0.5s)で調整できます。もっとゆっくり見せたいなら0.8sや1sに、キビキビ見せたいなら0.3s程度に変えてみてください。なおopacityは、ブラウザが効率よくアニメーションできるプロパティとして知られており、動作が軽く滑らかになりやすいという利点もあります。

細かい点ですが、デモのhrefにはサンプル用のダミーURLを入れています。実際のボタンではリンク先を差し替えてください。擬似要素はz-indexで背面(マイナス値)に置いているため、ボタンのテキストは常に手前に表示されます。もしテキストが見えない場合は、親要素のz-indexpositionの指定を見直すと解決します。

まとめ

  • 単色ボタンはtransitionだけでふわっと色が変わる
  • グラデーションはbackground-image扱いで補間できないため、transitionが効かない
  • 解決策は、::before::afterに2つのグラデーションを重ね、::beforeopacityでフェードさせること

「なぜ効かないのか」を理解しておくと、グラデーション以外の背景アニメーションでつまずいたときにも応用が利きます。擬似要素の重ね合わせは他の演出でも役立つテクニックなので、この機会に押さえておくと便利です。

IPPEI FUKUTA(株式会社バッズブルー 代表)

IPPEI FUKUTA(株式会社バッズブルー 代表)

WordPress専門のWeb制作者として15年・150サイト以上を担当。現場でつまずいた問題と解決策を、同じ制作者・フリーランスの方に向けて発信しています。無料のWeb便利ツール集「バドツール」を開発・運営中。