【CSS】ボタン 〜グラデーションから枠線に変化する〜

CSS

ボタンの概要

ホバー時にボタンを変化させるやり方はたくさんありますが、本記事では「グラデーションから枠線に変化する」やり方についてご紹介いたしますので、よろしければご参考ください。

今回ご紹介するボタンは下の「お問い合わせ」ボタンとなります。実際にデモボタンをホバーしてご確認してみてください。

お問い合わせ

ポイントは次のとおりです。

  • ボタンの背景はグラデーションで作成
  • ホバー時は白抜きする
  • ホバー時の枠線はグラデーションを維持する

枠線にグラデーションをかけるので「border」を使用しておりません。疑似要素に白背景を作成して重ねていくというやり方になります。

このときに重なり順をコントロールする必要がありますので、z-indexをうまく使ってスタイルをあてていきます。

 考え方:z-indexをうまく使って要素を重ねることでホバー時の変化を実現する

サンプルコード

サンプルコードは下記のとおりとなります。多少モディファイする必要があると思いますが、ベース部分はコピペでご使用できると思います。

<a class="grad-btn" href="#">お問い合わせ</a>
.grad-btn {
  position: relative;
  display: inline-block;
  width: 150px;
  max-width: 100%;
  padding: 14px 10px;
  background: linear-gradient(90deg, #FA41CC 0%, #6020B0 100%);
  border-radius: 5px;
  color: #fff;
  font-size: 14px;
  text-align: center;
  text-decoration: none;
  transition: 0.25s;
  z-index: 0;  /* z-indexをauto以外にする */
}

.grad-btn:hover, .grad-btn:focus {
  color: #6020b0;  /* ホバー時の文字色を指定 */
}

.grad-btn:hover::before, .grad-btn:focus::before {
  content: "";
  position: absolute;
  background: #fff;  /* 白抜き用の背景 */
  top: 2px;
  right: 2px;
  bottom: 2px;
  left: 2px;
  border-radius: 3px;  /* border-radiusを調整 */
  z-index: -1;  /* z-indexを指定 */
}

コードのポイントは下記のとおりとなります。

  • 通常時のスタイル
    • グラデーションにする → 「background」に「linear-gradient」を指定
    • 疑似要素でposition:absoluteを使う → 「position:relative」を指定
    • 重なり順の制御 → 「z-index:auto以外」を指定
  • ホバー時のスタイル
    • 文字色を変更 → 「color」で色を指定
    • 疑似要素で白背景を作成 → 「position:absolute」と「background」で指定
    • 重なり順の制御 → 「z-index:-1」を指定

「白背景の作成」と「重なり順の制御」についてはもう少し詳しく説明いたします。

白背景の作成

グラデーションの枠線を作るために、グラデーション背景に白背景を重ねて作成します。

このとき白背景のサイズは親要素より少し小さいサイズにする必要があります。

親要素の幅と高さから直接widthとheightを指定して天地中央揃えをするやり方もありますが、位置指定を利用したほうが簡単に記述できます。

「position:absolute」のテクニックとして、「top:0, right:0, bottom:0, left:0」とすべて0を指定することで「position:relative」を指定している親要素と同じサイズを作成するやり方があります。

これを少し応用して「top:2px, right:2px, bottom:2px, left:2px」とすれば親要素よりも2px小さいサイズを作成することができます。これを親要素に重ねることで枠線を作成することができます。

この「2px」の指定が枠線の太さになります。
後は「border-radius」を少し調整して「5px → 3px」とすればきれいな枠線となります。

重なり順の制御

白背景を作成したら重なり順を制御するためにz-indexを指定していきます。

疑似要素で白背景を作成した段階では、下記のような順番で重なっております。

   上:白背景(疑似要素) > テキスト(お問い合わせ) > 親要素(aタグ):下 

疑似要素で作成した白背景は「position:absolute」で作成しましたので、このままではテキストの上に配置されてしまいます。

ここでテキストのz-indexは内部的に0となっておりますので、疑似要素を0より小さい値すなわちマイナス値で設定すれば良いのでは?と思いますが、白背景(疑似要素)に「z-index=-1」を設定しますと今度は下記のような順番となります。

   上:テキスト(お問い合わせ) > 親要素(aタグ) > 白背景(疑似要素) :下 

z-index=-1を設定することで親要素の下に子要素を配置することができてしまいます。

つまりこの場合では白背景(疑似要素)にz-index=-1を設定してしまうと、親要素(aタグ)の下に配置されてしまい白背景が見えなくなってしまいます。

「親要素の下に子要素を配置しないようにする」つまり「 親要素に対してz-index=-1を効かないようにする」には親要素がスタッキングコンテキストを持てばよいということになります。

従いまして親要素に「z-index=auto以外」を設定すれば親要素の下に白背景がくることなく、テキストと白背景の重なり順を指定することができます。。

参考:スタッキングコンテキストにつきましてはこちらの記事をご参考ください。
z-index=-1が効かない理由とは?
こちらの記事は「親要素に対してz-index=-1を効くようにする」という内容になっております。今回はその考え方を逆に使っております。

補足:テキストをspanタグで指定して、そのspanタグに対して「z-index=1」を指定しても実現できます。こちらの方法でしたら親要素に「z-index=auto以外」を指定する必要はございません。

余談:親要素には「z-index」を指定する代わりに、「opacity:0.99」とか「transform: scale(1)」とか設定してもきちんとした重なり順となります。

まとめ

「【CSS】ボタン 〜グラデーションから枠線に変化する〜」についてまとめてみました。

ぜひサンプルコードをご参考にしていただければと思います。

要素の重なり順を制御するところでスタッキングコンテキストの考え方が必要となりますが、ここを理解して頂ければ色々と応用していただくことも可能かと思います。