はじめに
ちょっと凝った見た目のUI部品が欲しいとき、さくっと作れるとライブラリ探す手間が省けてうれしい。
僕はその基準を「CSSだけで作れる見通しが立つか」に置いている。
UI部品は、パフォーマンスの面でも、複雑さの面でも、極力JSをへらすことが望ましい。
jQueryみたいなライブラリに依存してしまうのは最悪だ。他のライブラリの環境下で使えない。
ということで、JSを使わんで済むなら、圧倒的にそのほうがいい。
そのためには、日頃から「この部品の仕組みはどうなっているか」と疑問を持ち、「自分で作るならどう作るか」みたいなことを考えて、使える引き出しを増やしていくのがいい。
今回は、スライドスイッチをCSSだけで作ってみた。こんなん。
せっかくなので、何番煎じかわからんけど作り方を残しておく。
設計する
まずは、どうやって実現するか考えてみる。
以下の仕組みは使えそう。
- label要素で囲われたチェックボックスは、label要素内の何かをクリックすることによってON/OFF切り替わる。
- :checked疑似クラスと隣接セレクタを使ったトリックで、チェックボックスのON/OFFによってチェックボックスの隣接要素に動きをもたせる事ができる。
この2つから、単純にDOM構成を考えると以下のようになる。
大体、似たようなことやろうと思うとお世話になる構造。
なお、このUIのクラス名はslide-switch
とした。
<label class="slide-switch">
<input type="checkbox"/>
<!-- ↑ のON/OFF によって ↓ の要素を動かす仕掛け -->
<span></span>
</label>
次に、UI部品を構成する部品を考えると、3つで作れるとわかる。
リアルで同じ見た目のものを作ろうとしても同じ構成になるだろう。
- 持って動かすツマミ部分。
- スライドする中の板の部分。
- 穴の部分。中身をここから覗かせる。
サイズ感はそれぞれこんな感じ。
実装する
穴を作る
今回は周りを丸く切り抜くイメージなので、border-radius
をしっかりかけた。
.slide-switch {
position: relative;
display: inline-block;
width: 3em;
height: 1.5em;
border-radius: 1.5em;
overflow: hidden;
}
position: relative
は、子要素にabsolute
効かせる予定なのでつけとかないと中身が飛んでいく。
穴のように切り抜くので、overflow: hidden
を忘れてはいけない。
また、チェックボックスは仕掛け上必要だが見かけ上必要ないので消しておく。
.slide-switch input {
display: none;
}
スライドする部分を作る
余白左 : ツマミ : 余白右 = 1 : 1 : 1 で、穴から出すのは 余白左+ツマミ もしくは ツマミ+余白右 と考えているので、サイズは穴の1.5倍。
チェックボックスの隣接要素のspanをそれにする。
.slide-switch span {
position: absolute;
display: block;
width: 4.5em;
height: 100%;
left: 0;
background-color: #E3E3E3;
transition: all 300ms linear;
}
移動と色変えをアニメーションしようとしてるので、left
, background-coor
, transition
を設定している。
隣接セレクタのトリックがこちら。
.slide-switch input:checked ~ span {
left: -1.5em;
background-color: limegreen;
}
チェックボックスがONのとき、スライドする板の色を緑にしつつスライドさせている。
初期値と移動後のleftの値を入れ替えると、ON/OFFの位置が逆転する。
移動距離は1/2穴幅。計算して入れた。穴幅とつまみ幅の比率によって可変。
つまみを作る
spanの中にゴチャゴチャ要素追加してもいいが、DOM的には少ないほうが嬉しいかなーということで、疑似要素として実装。
.slide-switch span::after {
content: '';
position: absolute;
display: block;
width: 1.3em;
height: 1.3em;
border-radius: 1.3em;
left: 1.6em;
top: 0.1em;
background-color: white;
}
穴より若干小さくして、スライドする板の真ん中に配置した。
position: absolute
は多分使わなくてもいけるが、数値計算してきちっと割り当てたほうが気分いいためそうした。
おわりに
作ったスライドスイッチをこちらに示す。
なお、ONのときに文字表示したりなど、若干の改造をしている。
See the Pen CSS Only slide switch by kakusuke (@kakusuke) on CodePen.