Posted at

labelにforを使わずに、cssだけでトグルボタンを作る


トグルボタンの基本

onの時に押すとoffに。offの時に押すとonになるボタンです。基本的な構造はチェックボックスと同じで、見た目が違うだけです。


labelにforを使ったパターン

inputにid属性を設定し、labelのfor属性で対応するチェックボックスを指定してやります。


html-1

  <input id="toggle-1" type="checkbox" name="btn1">

<label for="toggle-1">ボタン1</label>

これでlabelタグを押すことでチェックボタンを押したことと同じになるので、あとはinputは非表示にするなりlabelを装飾するなりして、体裁を整えてやればよいというすんぽう。

キモはonのときとoffのときの表示状態を変えてやることです。

onというのはinput:checkedの時です。

inputの隣にlabelを配置することでcssセレクターで指定することができますのでそのように指定します。


css-1

/* チェックボックスは非表示 */

input[type="checkbox"] {
display: none;
}
/* ボタンとして押すのはlabelなので枠線を作る。offのときの表示です。 */
label {
border: 3px outset #888;
background-color: white;
color: black;
}

/* onのときの表示 */
input:checked + label {
border: 3px inset #888;
background-color: black;
color: white;
}



labelにforを使わないパターン

labelの子要素として、inputを配置してやることでlabelタグにforを使わない、すなわちinputにidが不要な書き方ができます。


html-2

  <label>

<input type="checkbox" name="btn2">
<span>ボタン2</span>
</label>

あとはonとoffの表示状態の切り替えです。

ポイントはlabelタグではなく子要素のspanです。

cssは子要素から親要素を指定するセレクターは無いので、inputをlabelの子に入れてしまうとcheckedを判定することができません。

そこで、inputの兄弟要素であるspanをボタンの表示として使おうということです。


css-2

/* チェックボックスは非表示(※css-1と同じ) */

input[type="checkbox"] {
display: none;
}

/* offの表示状態 */
label > input + span {
border: 3px outset #888;
background-color: white;
color: black;
}
/* onの表示状態 */
label > input:checked + span {
border: 3px inset #888;
background-color: black;
color: white;
}
/* labelのhover時もこのように書ける */
label:hover > input + span {
color: red;
}


動的なUIを作る場合、トグルボタンごときにいちいちidを振りたくない。そんなの管理もしたくない。

そういう時にはこの書き方が使えると思います。