2019/11/01 (更新日: 2019/12/17)

【CSS】くるっと回転する3Dボタンの作り方

今回の記事では、ホバーするとくるっと回転する3Dボタンの作り方を紹介します。

初心者にも分かりやすく、ボタンが完成するまでの過程を1から手順を追って解説しています。『オシャレな3Dボタンを設置したい!』という方は是非ご覧ください!

作成する3Dボタンの完成品がこちらです。

See the Pen
MWWrYKv
by matsuo9749 (@matsuo9749)
on CodePen.

では、1から作成手順を説明していきたいと思います。

ボタンの土台を作成

まずはボタンの土台を作成していきます。下記はHTMLです。

<div class="scene">
 <div class="btn">
  <a href="#">
   <div class="side default-side">Button</div>
   <div class="side hover-side">Click!</div>
  </a>
 </div>
</div>

複雑なHTMLではありません。

ポイントとしては、実際に見えている表面と、ホバー時の裏面を区別するために、2つに分けている点です。

次にCSSを設定していきます。

* {
  box-sizing: border-box;
}

全体に【box-sizing: border-box;】を設定しています。【box-sizing: border-box;】を設定することで、paddingとborderを幅(width)と高さ(height)に含めることができます。

このボタンではborderを扱っていますが、borderの太さは%指定できないため、ズレが生じてしまいます。それを防ぐために【box-sizing: border-box;】を設定しています。

次はボタン全体のCSSです。

.btn {
 height: 80px;
 width: 150px;
}

このように、高さ(height)を80px、幅(width)を150pxに設定しています。

次は、表面と裏面どちらも適用されるCSSの設定です。

.side {
 position: absolute;
 width: 100%;
 height: 100%;
 display: flex;
 justify-content: center;
 align-items: center;
 font-size: 1.5em;
 font-weight: bold;
}

長いので重要な部分のみ説明します。

まず【position: absolute;】ですが、こちらは表面と裏面を重ねるための設定です。

下記は、ボタンの中の文字を中央配置するためのCSSです。

display: flex;
justify-content: center;
align-items: center;

【display:flex】と指定することで、要素を『Flexboxコンテナー』として定義することができ、子要素に対して様々な『Flexboxアイテム』を使用することができます。【justify-content】【align-items】はどちらもFlexboxアイテムです。

【align-items: center;】は、縦軸に対して中央に配置されます。【justify-content: center;】は、横軸に対して中央に配置されます。

これらは文字を中央に配置したいときに非常に便利なので是非活用してみてください。

次はボタンの表面と裏面それぞれのCSSを設定しましょう。

/* ボタンの表面 */
.default-side {
 background-color: white;
 border: 4px solid #069;
 color: #069;
}
/* ボタンの裏面 */
.hover-side {
  color: white;
  background-color: #069;
}

こちらは単純なCSSですね。

表面のみ枠線(border)を設定しており、幅を4px、色を#069としています。

ここまで設定したボタンを確認してみましょう。

See the Pen
NWWXKNy
by matsuo9749 (@matsuo9749)
on CodePen.

裏面しか描画されていないように見えます。これは表面・裏面共に【position: absolute;】を指定している影響で、要素が重なっているからです。試しにHTMLの裏面の部分を消してみます。

See the Pen
XWWVJPx
by matsuo9749 (@matsuo9749)
on CodePen.

きちんと表面を描画できていることが確認できます。

このままでは、ただの平面のボタンなので、回転させるCSSを記述していきます。

回転させるCSSを設定

まずは3D空間の設定です。

.scene {
  perspective: 1000px;
} 

【perspective】は要素に3D効果の奥行きの深さを指定する際に使用するものです。数値が高いほど3D効果は薄くなります。また、3Dにする要素全体にCSSを設定しなければなりません。

なぜ、数値が高いほど3D効果が薄くなるのかというと、【perspective】の数値は視点から要素への距離を示しているからです。大きいほど歪みが小さく、小さいほど歪みが大きくなります。

比較してみましょう。上が【perspective】を設定しているボタン、下が【perspective】を設定していないボタンです。

See the Pen
gOOXQad
by matsuo9749 (@matsuo9749)
on CodePen.

このように、【perspective】を設定することで奥行きを出すことができます。

 

次はボタンを回転させる設定です。

.hover-side {
  color: white;
  background-color: #069;
  transform: rotateX(90deg); /* 追加 */
}  

こちらは裏面の設定です。回転処理を追加しています。

【transform: rotateX(90deg);】とは、X軸に90度傾けるという設定になります。

このCSSを追加すると、裏面が消え、表面のみ描画されます。

例えば、一枚の薄い紙を真正面から見ると平面に見えますが、その紙をX軸に正確に90度傾けるとほぼ何も見えない状態になると思います。それと同じ原理だと思ってください。

次は、ボタンホバー時のCSSです。

.btn:hover {
  transform: rotateX(-90deg) ;
}

【transform: rotateX(-90deg);】によって表面・裏面共にX軸に-90度傾きます。

つまり、ホバーすることによって、表面のX軸が0度から-90度になることで消え、裏面のX軸が-90度から0度になることで表示されます。

このままではホバー時に一瞬で裏面に切り替わってしまうので、下記のCSSを追加します。

.btn {
    position: relative;
    height: 80px;
    width: 150px;
    transform-style: preserve-3d; /* 追加 */
    transition: transform 300ms ease-in-out; /* 追加 */
}

【transform-style】は、子要素がフラットに描画されるか立体的に描画されるかを指定するものです。

【transform-style: preserve-3d;】を設定することで、子要素に個別に指定した3D空間での変形が適用され、親要素と子要素は3D空間上で別々に配置されます。

【transition: transform 300ms ease-in-out;】は、ホバー時の動きが終わるまでの時間と、変化のタイミング・進行割合を指定しています。

終わるまでの時間は300ms(0.3秒)で、変化のタイミングははease-in-out(ゆっくり始まってゆっくり終わる)に設定しています。

ここまで設定したボタンを確認してみましょう。

See the Pen
poopjvM
by matsuo9749 (@matsuo9749)
on CodePen.

だいぶ近づいてきましたね。完成までもう少しです!

このままではただ、表面と裏面が切り替わるだけで、見た目も変なので、奥行きを設定していきます。

ホバー時の奥行き設定

まずは表面の設定です。

.default-side {
  background-color: white;
  border: 4px solid #069;
  color: #069;
  transform: translateZ(40px); /* 追加 */
} 

【transform: translateZ(40px);】によってZ軸方向(奥行き)の設定をしています。指定する数値は、ボタンの高さ(height)の半分に設定します。

イメージしづらいと思うので確認してみましょう。

See the Pen
wvvpKEV
by matsuo9749 (@matsuo9749)
on CodePen.

このように、ホバー時に表面のみ奥行きが生じているのがわかります。次は裏面に奥行きを出します。

.hover-side {
  color: white;
  background-color: #069;
  transform: rotateX(90deg) translateZ(40px); /* Z軸追加 */
}  

裏面に関しても、表面と同じ【translateZ(40px)】を設定します。下記が設定後のボタンです。

See the Pen
VwwyvgE
by matsuo9749 (@matsuo9749)
on CodePen.

一見完成したかのように見えますが、2つの問題があります。1つ目は要素のズレがあること、2つ目は形した要素の背面が描画されていることです。では、訂正していきましょう。

まず、一つ目の要素のズレですが、こちらは奥行きの設定によるものです。

.btn {
    position: relative;
    height: 80px;
    width: 150px;
    transform-style: preserve-3d;
    transition: transform 300ms ease-in-out;
    transform: translateZ(-40px); /* 追加 */
}

このように、ボタン要素自体に奥行きを戻すように設定します。確認してみましょう。

See the Pen
LYYeGRX
by matsuo9749 (@matsuo9749)
on CodePen.

このように、ボタンは元の場所に戻すことができました。しかしまだ、ホバー時に適用されていません。

こちらのズレは、【translateY】によって戻します。

/* ボタンホバー時の設定 */
.btn:hover {
 transform: rotateX(-90deg) translateY(40px);
}

なぜ【translateZ】ではなく【translateY】なのかというと、ホバー時の動きがY軸方向だからです。

表面のボタンは【translateZ】ホバー時のボタンは【translateY】で奥行きのズレを戻すことができます。

最後に変形した要素の背面を消したいと思います。こちらは簡単です。

.side {
  position: absolute;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.5em;
  font-weight: bold;
  backface-visibility: hidden; /* 追加 */
}

表面と裏面どちらも適用されるsideに【backface-visibility: hidden;】を追加します。

【backface-visibility: hidden;】は、要素の背面を描画せず、要素自体がないように表示される設定です。確認してみましょう。

See the Pen
rNNpxGv
by matsuo9749 (@matsuo9749)
on CodePen.

変形した要素の背面が消えました。これで3Dボタンの完成です。お疲れ様でした!

まとめ

以上、くるっと回転する3Dボタンの作り方の手順を1から解説しました。

少しアレンジするだけで、下記のようなTwitterボタンも作ることができます。是非ご活用下さい!

Twitter
Follow!

 

ご質問等ございましたらTwitterお問い合わせからご連絡ください。

Webエンジニアについて詳しく知りたい方はこちら
Webエンジニアの仕事内容・年収・将来性
本気でWebエンジニアになりたい方はこちら
未経験からWebエンジニアに転職する方法
フリーランスに興味ある方はこちら
フリーランス言語別案件数ランキング