フローティングボタンのアニメーションをCSSで作った
はじめに
初めまして、ポートのフロントエンドを担当している @fujita です。
業務で CSS アニメーションを使ったアニメーションの実装を行なったのでそれについて書いていこうと思います。
完成品
解説
CSS で装飾する
HTML は以下の通りです。こちらを SCSS で装飾していきます。
<button class="btn" type="button">
<span class="dot"></span>
<span class="rod1"></span>
<span class="rod2"></span>
<span class="rod3"></span>
</button>
SCSS は下記の通りです。
.btn {
border: 3px solid blue;
border-radius: 50%;
bottom: 30px;
height: 60px;
position: fixed;
right: 30px;
width: 60px;
background-color: #fff;
}
.dot
は左側真ん中の点の style を指定しています。擬似要素では左側上下の点の style を指定しています。
.dot,
.dot::after,
.dot::before {
background-color: blue;
border-radius: 50%;
content: '';
height: 5px;
position: absolute;
width: 5px;
}
.dot {
left: 14px;
top: 24.5px;
&::before {
left: 0;
top: 8px;
}
&::after {
bottom: 8px;
left: 0;
}
}
.rod
は右側真ん中の棒の style を指定しています。擬似要素では右側上下の棒の style を指定しています。
.rod1,
.rod2,
.rod3 {
background-color: blue;
border-radius: 10px;
content: '';
display: block;
height: 5px;
position: absolute;
width: 18px;
}
.rod1 {
right: 13px;
top: 17px;
}
.rod2 {
right: 13px;
top: 24.5px;
}
.rod3 {
bottom: 16px;
right: 13px;
}
ここまでの HTML、CSS で基本の表示は完成になります。
アニメーションを実装する
animation プロパティは複数のプロパティの一括指定プロパティで、アニメーションを適用することができます。
下記ではanimation-name
、animation-duration
、animation-fill-mode
を指定しています。
animation-name
使用したい@keyframes
アットルールの名前を指定します。
animation-duration
1 回のアニメーション周期が完了するまでの所要時間を設定します。
animation-fill-mode
CSS アニメーションの実行の前後に対象にスタイルを適用するかを設定します。今回はforwards
を指定して@keyframes で設定した最後のキーフレームの計算値を保持しています。
.close > .rod1 {
animation: rod-close1 .75s forwards;
}
.close > .rod2 {
animation: rod-close2 .75s forwards;
}
.close > .rod3 {
animation: rod-close3 .75s forwards;
}
.close > .dot {
animation: dot-close .75s forwards;
}
.open > .rod1 {
animation: rod-open1 .75s forwards;
}
.open > .rod2 {
animation: rod-open2 .75s forwards;
}
.open > .rod3 {
animation: rod-open3 .75s forwards;
}
.open > .dot {
animation: dot-open .75s forwards;
}
@keyframes
アットルールは下記のような構文で CSS アニメーションの中間ステップを制御することができます。
@keyframes slidein {
from {
transform: translateX(0%);
}
to {
transform: translateX(100%);
}
}
from は0%
を表し、to は100%
を表します。今回は中間地点も指定するのでわかりやすく0%
と100%
で指定しています。
@keyframes dot-close {
0% {
opacity: 1;
}
30% {
opacity: 1;
}
31% {
opacity: 0;
}
100% {
opacity: 0;
}
}
@keyframes dot-open {
0% {
opacity: 0;
}
70% {
opacity: 0;
}
71% {
opacity: 1;
}
100% {
opacity: 1;
}
}
@keyframes rod-close1 {
0% {
width: 18px;
}
30% {
transform: none;
width: 27px;
}
70% {
transform: translateY(8px) rotate(0deg);
}
100% {
transform: translateY(8px) rotate(45deg);
width: 27px;
}
}
@keyframes rod-open1 {
0% {
transform: translateY(8px) rotate(45deg);
width: 27px;
}
30% {
transform: translateY(8px) rotate(0deg);
}
70% {
transform: none;
width: 27px;
}
100% {
width: 18px;
}
}
@keyframes rod-close2 {
0% {
opacity: 1;
width: 18px;
}
30% {
width: 27px;
}
69% {
opacity: 1;
}
70% {
opacity: 0;
}
100% {
opacity: 0;
width: 27px;
}
}
@keyframes rod-open2 {
0% {
opacity: 0;
width: 27px;
}
30% {
opacity: 0;
}
31% {
opacity: 1;
}
70% {
width: 27px;
}
100% {
opacity: 1;
width: 18px;
}
}
@keyframes rod-close3 {
0% {
width: 18px;
}
30% {
transform: none;
width: 27px;
}
70% {
transform: translateY(-8px) rotate(0deg);
}
100% {
transform: translateY(-8px) rotate(-45deg);
width: 27px;
}
}
@keyframes rod-open3 {
0% {
transform: translateY(-8px) rotate(-45deg);
width: 27px;
}
30% {
transform: translateY(-8px) rotate(0deg);
}
70% {
transform: none;
width: 27px;
}
100% {
width: 18px;
}
}
JavaScript でアニメーションを発火させる
JavaScript は下記の通りです。
addEventListener
メソッドを使用して btn をクリックしたら btn の class を付け替えるようにしています。
const btn = document.querySelector('.btn');
btn.addEventListener('click', () => {
if (btn.classList.contains('close') === false) {
btn.classList.add('close');
btn.classList.remove('open');
} else {
btn.classList.remove('close');
btn.classList.add('open');
}
});
完成
以上の方法でフローティングボタンのアニメーションを実装しました。
参考文献
Discussion