トグルボタンと言うのは次のようなやつです。
クリックすると、中の白い丸が左右に動きます。ヒュッヒュッ!
こいつをさっくり作る方法を考えてみます。
FlexBoxの中にdivを三つ並べる
<div id="container" class="container">
<div id="left"></div>
<div class="switch"></div>
<div id="right"></div>
</div>
真ん中のclass="switch"のやつがヒュンヒュン動く白い丸になります。
それっぽくスタイルを整えてみます。
.container {
border-radius: 9999px;
background-color: gray;
width: 45px;
display: flex;
margin: 5px;
padding: 1.5px;
}
.switch{
background-color: white;
height: 15px;
width: 15px;
border-radius: 9999px;
}
見た目はそれっぽくなりました。
しかし、もちろん現時点ではクリックしても動きません。
こいつを左右に動かすにはどうしたらいいでしょう?
左右のdivの幅をflexで変える
勘のいい方は既にお気づきの通り、左右の空divがキーとなります。
たとえば白い丸を右に動かしたければ、
- 左の空divの幅をいっぱいに広げる
- 右の空divの幅をゼロにする
という手順により達成できます。
左に動かしたければ左右を逆にすればいいだけです。
「幅をいっぱいに広げる」「幅をゼロにする」作業は、flexで実装可能です。
//幅がゼロ
.close{
flex: none;
}
//幅がいっぱい
.open{
flex: auto;
}
あとは「コンテナをクリックすると、左右の空divのクラスが切り替わる」という仕組みを作るだけです。
ReactやVueなら秒で実装できますが、ここはvanilla JSでやってみましょう。
JavaScriptでイベントリスナをくっつける
//コンテナと左右の空divを拾う
const container = document.getElementById("container");
const left = document.getElementById("left");
const right = document.getElementById("right");
//要素を受け取り、open/closeクラスを逆にする関数
const toggleIsOpen = (el) => {
const isOpen = el.classList.contains("open");
if (isOpen) {
el.classList.remove("open");
el.classList.add("close");
} else {
el.classList.remove("close");
el.classList.add("open");
}
};
//上記関数を使い左右の空divのopen/closeクラスを書き換える
const switchButton = () => {
toggleIsOpen(left);
toggleIsOpen(right);
};
//コンテナをクリックしたらその関数を実行する
container.addEventListener("click", switchButton, false);
open/closeの初期クラスを加える
上記のJavaScriptは、「対象エレメントのクラスリストにopenがあればそれをcloseに書き換える」「closeがあればopenに書き換える」という仕組みなので、openクラスとcloseクラスを左右の空divに付け加える必要があります。
<div id="container" class="container">
<div id="left" class="close"></div>
<div class="switch">
</div>
<div id="right" class="open">
</div>
</div>
アニメーションを付ける
左右の空divにtransition-duration
を付ければ、一瞬で切り替わらずにヒュッヒュッと動かすことができます。
私はスピード感のあるアニメーションが好きなので、0.1秒でヒュッ!!!と切り替わるように設定します。
.space{
transition-duration: 100ms;
}
左右の空divに上記クラスを書き加えれば、アニメーションが実装できます。
<div id="container" class="container">
<div id="left" class="close space"></div>
<div class="switch">
</div>
<div id="right" class="open space">
</div>
</div>
これで完成。
ね、簡単でしょ?
Codepen
参考
Applying transition on flexbox justify-content property -StackOverFlow