チェックボックス・ラジオボタンをカスタマイズする機会があったので、シンプル版をまとめました。
イメージ
デモ
SCSS版: http://jsdo.it/butchi/wXVq
生CSS版: http://jsdo.it/butchi/00EB
ポイント
- input要素の代わりに擬似要素を使って部品の見た目を整えます。
- inputは空要素のため、それ自身にbefore/after擬似要素を設定できません。
そのため、隣接セレクタ"+"(場合によっては兄弟セレクタ"~")を使って
隣接要素にbefore/afterを設定します。 - タブでの挙動を保証するため、input要素を
display: none
にはしません。
アドバイス
- 今回はbeforeに未チェック時の背景、afterにチェック時の点を割り当てましたが、
スプライト画像で未チェック・チェックを切り替える場合は
beforeだけにしてbackground-positionを切り替えるといいと思います。 - beforeだけの場合は擬似要素を
position: absolute
ではなくposition: relative
にした方が収まりがいいかもしれません。 - 実際実装した時はチェック時にCSSアニメーションさせましたが、それもそれなりに大変でした。
ソース
(CSS版)
body {
background-color: #fff;
}
input[type="checkbox"],
input[type="radio"] {
position: absolute;
width: 0;
height: 0;
top: 0;
left: 0;
opacity: 0;
}
input[type="checkbox"] + *,
input[type="radio"] + * {
position: relative;
display: inline-block;
box-sizing: border-box;
}
[type="checkbox"] + * {
margin-left: 17px;
padding-left: -3px;
line-height: 12px;
}
[type="checkbox"] + *::before,
[type="checkbox"] + *::after {
content: "";
display: block;
position: absolute;
box-sizing: border-box;
width: 12px;
height: 12px;
left: -14px;
top: 0px;
}
[type="checkbox"] + *::before {
background-color: #fff;
border: 1px solid #000;
}
[type="checkbox"]:checked + *::after {
position: absolute;
width: 6px;
height: 6px;
margin-left: 3px;
margin-top: 3px;
background: #000;
}
[type="radio"] + * {
margin-left: 17px;
padding-left: 0;
line-height: 16px;
}
[type="radio"] + *::before,
[type="radio"] + *::after {
box-sizing: border-box;
content: "";
display: block;
position: absolute;
width: 16px;
height: 16px;
left: -16px;
top: 0px;
}
[type="radio"] + *::before {
background-color: #fff;
border: 1px solid #000;
border-radius: 16px;
}
[type="radio"]:checked + *::after {
position: absolute;
width: 8px;
height: 8px;
margin-left: 4px;
margin-top: 4px;
background: #000;
border-radius: 8px;
}
[type="checkbox"]:disabled + *::before,
[type="checkbox"]:disabled + *::after,
[type="radio"]:disabled + *::before,
[type="checkbox"]:disabled + *::after {
opacity: 0.25;
}
[type="checkbox"]:focus + *::before,
[type="radio"]:focus + *::before {
box-shadow: 1px 1px 0px #000;
}