javaScriptを使わずにHTML&CSSだけでON/OFFスイッチを作ります。
Webのサービス・アプリの設定画面でよく見るやつで、トグルボタン、トグルスイッチとも言います。
だれでも分かるように、サンプルコードを少しずつ作りながら説明します。
toggle
直訳では交互のもの、機構。
まずは完成したサンプルから。
See the Pen sample - on/off switch by tadtadya (@tadtadya) on CodePen.
これをHTMLとCSSだけでつくります。
javaScriptを使わないで作る
サンプルをつくっていく前に、JavaScriptを使わないメリットから。
HTMLとCSSだけでつくるとWebサーバにリクエストする回数を最小限にできます。そのしくみは、
- ブラウザからhttpリクエストを送信する。
- Webサーバーから、すべてのコンテンツのHTMLを返す。
- ページを最初に表示するとき、いらないものはかくす。
- スイッチの切り替えをCSSでコントロールする。
これはスイッチのON/OFFの切り替えでページ遷移をしません。
また、コンテンツをリクエストで再取得しないとしても、JavaScriptのDOM操作がいらないので、その分だけブラウザの負荷を軽くできます。
あらかじめ、CSSですべての操作のスタイルが定義されているので、CSSOMの再展開がない。
(CSSOMはCSSのDOMみたいなもの。)
(JavaScriptのDOM, CSSOM操作の分がいらない。)
また、HTML, CSSに任せることでJavaScriptのコードを少なくできる。
サンプルコードの内容
今回はステップごとに進めていきます。分かりやすいところで区切っていくので必ず作れます。
サンプルコードでは次のコンテンツを用意します。
コンテンツ | 機能 |
---|---|
OFFスイッチ | チェックボックスをOFFにする。 |
ONスイッチ | チェックボックスをONにする。 |
スイッチのラベル | チェックボックスのラベル・テキスト。 |
ステップ1 - パーツを作る
はじめにそれぞれのパーツを用意します。骨組みはHTMLで肉付けはCSSです。
まだ動きの機能はありません。見た目だけを作ります。
<div class="main">
<h3>設定</h3>
<div class="item-frame">
<input type='checkbox' id='setting-item-1' class="checkbox" />
<label class="switch" for='setting-item-1'></label>
<label class="text" for='setting-item-1'>メールマガジンを配信する。</label>
</div>
<div class="item-frame">
<input type='checkbox' id='setting-item-2' class="checkbox" />
<label class="switch" for='setting-item-2'></label>
<label class="text" for='setting-item-2'>Twitterで配信する。</label>
</div>
<div class="item-frame">
<input type='checkbox' id='setting-item-3' class="checkbox" />
<label class="switch" for='setting-item-3'></label>
<label class="text" for='setting-item-3'>Facebookで配信する。</label>
</div>
</div>
これを実行してみましょう。
設定
完成とは程遠い、『HTMLの初級編か!?』っていう内容です。骨組みなのでこんなもんでしょう。
HTMLはこれで終わりです。あとはぜんぶCSSでやっちゃいます。
サンプルはサイトのスタイルが若干入っているので、実際はもっとショボい見た目になります。
ステップ2 - パーツに装飾をつける
まずは、このステップで作るすべてのCSSを見てみましょう。
.main h3 {
font-size: 1.5rem;
border-bottom: 7px double #ccc;
text-align: center;
margin: 2rem auto;
}
.main .item-frame {
margin: 1rem auto;
}
.main .text {
vertical-align: middle;
}
.main label {
cursor: pointer;
}
.main .switch {
position: relative;
}
.main .switch:before, .main .switch:after {
content: '';
vertical-align: middle;
display: inline-block;
}
.main .switch:before {
width: 2em;
height: 1em;
border: 2px solid #C4C9FF;
border-radius: 32px;
background: #999;
}
.main .switch:after {
position: relative;
width: 1em;
height: 1em;
background: #C4C9FF;
border-radius: 50%;
left: -2.2em;
}
すぐに分からなければ一気に見る必要はないです。少しずつ分解して説明します。
まずはどうでもいいところから
あまり重要でないところから片付けましょう。
// タイトル
.main h3 {
font-size: 1.5rem;
border-bottom: 7px double #ccc;
text-align: center;
margin: 2rem auto;
}
// 設定項目のフレーム
.main .item-frame {
margin: 1rem auto;
}
// 設定項目のラベル・テキスト
.main .text {
vertical-align: middle;
}
// カーソルをポインタに
.main label {
cursor: pointer;
}
説明はいらないですね? これでHTMLを実行するとこうなります。
設定
まぁ、こんなもんでしょ。やりたいことは何もしてないし。
スイッチ(とりあえず分解されたまま)
次にスイッチを作ります。::before, ::after擬似クラスを使います。
::before | ボタンの本体 |
::after | ボタンの動くところ。 |
HTMLのラベルで何もテキストがないのはそのため。
<label class="switch" for='setting-item-1'></label>
// スイッチの共通部
.main .switch:before, .main .switch:after {
content: "";
vertical-align: middle;
display: inline-block;
}
// スイッチの背景
.main .switch:before {
width: 2em;
height: 1em;
border: 2px solid #c4c9ff;
border-radius: 32px;
background: #999;
}
// スイッチの動くところ(◯の部分)
.main .switch:after {
width: 1em;
height: 1em;
background: #c4c9ff;
border-radius: 50%;
}
設定
スイッチのサイズはwidth, height、コンテンツのコーナーのところはborder-radius(ここで○も作る)、あとは色付けしました。
スイッチの部品はとりあえず完成です。ただバラバラに配置されてますね?
スイッチ(デフォルトの完成)
今度はバラバラになっている部品を統合しましょう。ついでに見えなくていいチェックボックスを隠します。
さっきのCSSに追加します。
.main .switch {
position: relative; // <--- ※追加
}
.main .switch:before, .main .switch:after {
content: "";
vertical-align: middle;
display: inline-block;
}
.main .switch:before {
width: 2em;
height: 1em;
border: 2px solid #c4c9ff;
border-radius: 32px;
background: #999;
}
.main .switch:after {
position: relative; // <--- ※追加
width: 1em;
height: 1em;
background: #c4c9ff;
border-radius: 50%;
left: -2.2em; // <--- ※追加
}
.main input { // <--- ※追加
display: none;
}
スイッチの動くところ(○の部分)の位置を左にずらすためにpositionとleftで調整しました。
leftの移動距離やスイッチのサイズはフォントサイズに合わせてemを使いました。pxのほうがズレはないです。
(でも周りのサイズが変わってもスイッチの大きさは変わらない。)
すべてが相対変化なのでズレないと思いますが、そのときは修正してください。
設定
これでスイッチの形ができましたがONになりません。動きの部分を付けてないからです。
(かくれたチェックボックスはON/OFFになっている。)
ステップ3 - スイッチの動きをコントロール
さぁ、ここがクライマックスです。今回の話でここ以外はどうでもいいです。
(色や形のスタイルは好みで変わってくるので。)
.main input:checked ~ .switch:before {
background: #00b715;
border-color: #84ff92;
}
.main input:checked ~ .switch:after {
background: #84ff92;
left: -1.1em;
}
スイッチがONになったときの動きはこれだけです。チェックボックスがONになったときにつくchecked属性のスタイルを定義するだけです。
(部品の色と丸の位置(left)を変えただけ。)
<input type="checkbox" id="setting-item-1" class="checkbox">
<input type="checkbox" id="setting-item-1" class="checkbox" checked="checked">
設定
スイッチが完成しました。
ちなみに、たったこれだけで済んでいるのは、HTMLのdivで作ったフレームが効いているからです。
各スイッチの親が違うので、inputでスタイルを定義しても問題ありません。
デフォルトをONにするには
いまスイッチのデフォルトはOFFですが、ONにするにはHTMLの<input>にchecked属性を付けます。
<div class="main">
<h3>設定</h3>
<div class="item-frame">
<input type='checkbox' id='setting-item-1' class="checkbox" checked="checked" />
<label class="switch" for='setting-item-1'></label>
<label class="text" for='setting-item-1'>メールマガジンを配信する。</label>
</div>
<div class="item-frame">
<input type='checkbox' id='setting-item-2' class="checkbox" checked="checked" />
<label class="switch" for='setting-item-2'></label>
<label class="text" for='setting-item-2'>Twitterで配信する。</label>
</div>
<div class="item-frame">
<input type='checkbox' id='setting-item-3' class="checkbox" checked="checked" />
<label class="switch" for='setting-item-3'></label>
<label class="text" for='setting-item-3'>Facebookで配信する。</label>
</div>
</div>
設定
実用的なデフォルト値はDBから取ってきた値とかになります。
(それでchecked属性を付けるか決めればいい。)
ステップ4 - そのほかのスイッチ
あらかじめ用意されたON・OFF用スイッチを使うのもありです。たとえば、WebフォントのFont Awesomeにもあります。
ON | https://fontawesome.com/icons/toggle-on?style=solid |
OFF | https://fontawesome.com/icons/toggle-off?style=solid |
設定
CSSだけ変更します。変更した部分はこんなかんじ。
.main .switch:before { // background
content: "";
width: 1.7em;
height: 1.5em;
padding: 0 0.2em;
border-radius: 32px;
background: #999;
}
.main .switch:after { // WebFont
position: relative;
content: "\F204";
font-family: "Font Awesome 5 Free";
font-weight: 900;
font-size: 2em;
color: #c4c9ff;
background: rgba(255, 255, 255, 0); // backgroundは:beforeを使うので100%透明
left: -1.1em;
}
.main input:checked ~ .switch:before {
background: #84ff92;
}
.main input:checked ~ .switch:after {
content: "\F205";
color: #00b715;
}
もちろんですが、Webフォント・画像の読み込みの分だけHTML・CSSより重いです。
(svgなら変わらないと思うけど。)
まとめ
HTMLとCSSだけで動きをコントロールしているのは、チェックボックスと連動しているCSSのchecked疑似クラスです。
ポイントはこれだけといってもいいでしょう。
ほかにも、checked疑似クラスをつかうとHTML・CSSだけでできることがあります。
使い方は同じで、いろいろなことができますよ?