はじめに
疑似要素を使用してチェックボックスを作った際に、ブラウザ準拠のフォーカスを当てたかったのですが、どうしようか…と少々苦戦したので備忘録として残すために記事にしました。 (既出ネタだったらすいません)
また、元々は先輩がラジオボタンで似たようなことをしてたのを思い出し、それをチェックボックス版にしました。
なので0から私のアイディアという訳ではないです。(土下座)
結論
先に結論書いちゃいます。
疑似要素の下に普通のチェックボックス(input要素)置いちゃえ
以上です!
どういうこと?
では簡単に説明します。
の前に、カスタムチェックボックスを作成します。
事前準備
適当なinput要素、labelを用意。
<div class="checkbox-group">
<input type="checkbox" id="check1" class="checkbox">
<label for="check1" class="checkbox-label">チェック1</label>
</div>
すると上記のようなチェックボックスができるかと思います。
では上記に以下のスタイルを当てます。
.checkbox {
display: none;
}
.checkbox-label {
padding-left: 28px;
position: relative;
}
.checkbox-label::before {
content: "";
width: 20px;
height: 20px;
border: solid 2px #b0c4de;
background-color: #FFF;
border-radius: 4px;
position: absolute;
top: 0;
left: 0;
}
/* チェック済み */
.checkbox:checked + .checkbox-label::after {
content: "";
width: 16px;
height: 16px;
border-radius: 2px;
background-color: #b0c4de;
position: absolute;
top: 4px;
left: 4px;
}
すると
このようなチェックボックスができます。
ちなみにチェック済みの場合は…
こんな感じになります。
ここまでは、自分の好みのカスタムチェックボックスを作っていただいて大丈夫です。
考え方
では考え方ですが、文章は苦手なので、図で説明します。

(字が汚いのは申し訳ないです…ww)
…図でもわかりにくい説?
事前準備としてカスタムチェックボックスを作成しましたが、その際にinput要素をdisplay:none;
なりで非表示にするかと思います。
(実際に上記でもそのようにしています。)
ただそうするとフォーカスが当たらなくなってしまうので、
非表示にはせず、カスタムチェックボックスの真下に本来のチェックボックスを隠してやります。
そうすることで、あたかも疑似要素にフォーカスが合っているかのように見せています。
ということでスタイルは以下のようになります。
.checkbox {
/* display: none; */
outline-offset: 8px;
}
.checkbox-label {
/* padding-left: 28px; */
position: relative;
}
.checkbox-label::before {
content: "";
width: 20px;
height: 20px;
border: solid 2px #b0c4de;
background-color: #FFF;
border-radius: 4px;
position: absolute;
top: -1px;
left: -27px;
}
/* チェック済み */
.checkbox:checked + .checkbox-label::after {
content: "";
width: 16px;
height: 16px;
border-radius: 2px;
background-color: #b0c4de;
position: absolute;
top: 3px;
left: -23px;
}
したことは.checkbox
クラスのdisplay: none;
を削除、
outline-offset: 8px;
を擬似要素で隠れないように調整、
疑似要素の位置を調整くらいでしょうか。。
すると上記のようにフォーカスが当たるようになりました。
input要素自体を非表示にしていないので、スペースキーでチェックを入れたり、外したりも可能です!
考え方さえ分かってしまえば特に難しいことはしていないので、簡単だと思います。
まとめ
結論として、input要素を非表示にせずに、その上に擬似要素を置いてやればフォーカスが当たるようになります。
他に良き方法があったら教えていただきたいです。