【実用】CSSでボタンアニメーション

# この記事のターゲット
- CSSはある程度わかる
- アニメーションはよくわかんない
- ボタンにちょっとアニメーション乗せてリッチにしたい

# 最終成果物
これです。
ボタンを押したらちょっと沈んで実際に押してる感じがしますね。

![button-anime.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177043/2eb05322-1792-8789-4fc9-80c26298f50b.gif)


# 実装
大きく分けて以下の手順で進めます。
1. 土台になるhtmlの用意
2. 背景の設定
3. ボタンの配置
4. アニメーション実装


## 1. 土台になるhtmlの用意
さっくりと。

```index.html
<!DOCTYPE html>
<html lang ="ja">
<head>
    <link rel="stylesheet" href="../css/btn.css">
</head>
<body>
    <main class="stage">
        <a class="btn">押すなよ？絶対押すなよ？</a>
    </main>
</body>
</html>
```

## 2. 背景の設定
おしゃれにするだけです。
なくてもいいです。

```btn.css
* {
  margin: 0;
  padding: 0;
}

/**
* stage
*/
.stage {
  position: absolute;
  width: 100%; height: 100%;
  background-color: rgb(228, 217, 210);
  display: flex;
  justify-content: center;
  align-items: center;
}
.stage:before,
.stage:after { position: absolute; content: ""; display: block; }
.stage:before {
  top: 20px; left: 20px;
  width: calc(100% - 40px); height: calc(100% - 40px);
  border: solid 5px #6e5c60;
  border-radius: 30px;
  box-sizing: border-box;
  opacity: 0.3;
}
```

<img width="1680" alt="スクリーンショット 2019-11-13 9.02.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177043/c7196775-8f90-664d-32cb-e9a287b7fd59.png">


3. ボタンの配置
htmlの要素に用意しておいたbtnクラスにボタンっぽいcssを当てましょう。

```btn.css

...

/**
* stage
*/

...

/**
* btn
*/

.btn {
  position: absolute;
  cursor: pointer;
  background: #20b2aa;
  margin: 1em auto;
  padding: 20px;
  border-radius: 4px;
  box-sizing: border-box;
  color: #fff;
  text-align: center;
  text-decoration: inherit;
  box-shadow: 0 6px 0 #047c71, 0 12px 0 rgba(0,0,0,.2);
  transition: color .3s, background .3s, box-shadow .3s, transform 0.3s;
}

```

ここまででこんな感じ。
すでにだいぶそれっぽいですね。

<img width="1680" alt="スクリーンショット 2019-11-13 9.04.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177043/72ad246f-4d29-5d80-6822-9bc00118a252.png">

## 4. アニメーション実装
当然ですがこの状態では何をしてもボタンが変化しません。
ここから実際にアニメーションを実装していきます。


```btn.css

...

/**
* stage
*/

...

/**
* btn
*/

.btn {
...
}

.btn:hover {
	background: #3cc4bd;
	box-shadow: 0 3px 0 #12978d, 0 6px 0 rgba(0,0,0,.2);
	transform: translateY(3px);
}

.btn:active {
	color: #ddd;
	background: #12978d;
	box-shadow: 0 0 0 #047c71, 0 0 0 rgba(0,0,0,.2);
	transform: translateY(6px);
	transition-duration: .1s;
}
```

これでhover時とactive時の状態を決め、3つの状態を遷移させることで実現します。


主に利用するのはtransitionというプロパティとtransformというプロパティです。
詳しくみていきましょう。


### transition
まずはtransitionについてですが,これはcssの各classやidに付与するプロパティで、そのclassやidが要素に適用された時にどのように適用させるかを設定することができます。
この「どのように」という部分がアニメーションになっていて、ざっくり言えば「パッと切り替える」「じんわり切り替える」といった内容です。

ところで、すでにbtnクラスにはtransitionプロパティが付いていますね。
内容をみてみましょう。

```
  transition: color .3s, background .3s, box-shadow .3s, transform 0.3s;
```

ざっくり解説すると、左のプロパティを右の秒数かけて変化させる、という内容です。
ですのでcolor,backgroud,box-shadow,transformが0.3秒かけて変化することになります。
例えば、colorだけ0.3秒ではなく3秒にしてみるとどうでしょうか?
このクラスが適用されるタイミングは今の所リロードのタイミングしかないのでリロードしてみてください。
挙動が変わって文字色だけじんわり変わるようになったと思います。

さて、変化にかける時間しか指定できないのかというとそんなわけもなく、他にも指定できる設定があります。
もともと、transitionに関するプロパティはには以下の4種類があります。
一つずつみていきましょう。


#### transition-delay
名前の通り、delayを設定します。
1sと指定すればアニメーション開始が1秒後になります。

#### transition-duration
このプロパティがtransitionプロパティで指定したもので、アニメーションに何秒かけるかという設定です.

#### transition-property
transition-propetryにはtransitionを適用するプロパティを指定します。
今回で言えばcolorやbackgroundがこれにあたります。
ここで指定したプロパティに対して他の3つのtransitionが適用されることになります。

#### transition-timing-function
アニメーションの動き方です。
ease, linear, ease-in, ease-out, ease-in-outがあります。

ここまでわかった上でもう一度transitionプロパティをみると、transition-propertyとtransition-durationの組み合わせで指定していることがわかります。

transitionプロパティはこれら4つのプロパティを一度に指定できるもので、引数の順番は以下のようになります。

```
transition: [transition-property] [transition-duration] [transition-timing-function] [transition-delay]
```


### transform
次にtransformプロパティです。
これはそのclassが適用されている要素を変形させるプロパティです。
一口に変形と言ってもできることはある程度決まっていて、主に使うのは以下のあたりかと思います。
（他にもあるので気になったら調べてみてください。）

- rotateX()
- rotateY()
- rotateZ()
- translateX()
- translateY()
- translateZ()
- scaleX()
- scaleY()
- scaleZ()

今回ではbtn:hoverとbtn:activeでtransformを利用しています。
具体的には以下ですね。

```
	transform: translateY(3px);
```

translateY、ということでY軸方向に3px動かすという指定です。
ボタンを押している様子はtranslateYでボタンそのものを動かし、box-shadowの影を相対的に小さくしていくことで実現しているわけです。


## まとめ
今回はtransitionとtransformを使ったボタンアニメーションの実装について紹介しました。
サイズや配置場所を直せばすぐにでも使える形になっているかと思われます。
とはいえコピペで配置してしまうとちょっとした変更すらできなくて四苦八苦してしまうので多少なりとも理屈がわかっていると違うのではないかと思います。