コーディング

【サンプルコード紹介】チェックボックス/ラジオボタンをCSSで装飾する方法を解説。

2021.04.15

Takumi Kitamura

Takumi Kitamura

本記事では、お問い合わせフォームなどでよく使うチェックボックス/ラジオボタンの装飾方法とサンプルコードを紹介します。
味気のないデフォルトスタイルのチェックボックス/ラジオボタンを自在に装飾し、わかりやすいものに変えてみましょう。
チェックボックス/ラジオボタンのCSSでの装飾は通常よりも手間がかかるので、HTML/CSSに関して多少の知見がある方や、ウェブサイトを運用したり少し知識のある方に向けた記事になります。

基本のチェックボックス/ラジオボタンのHTML

基本的なラジオボタンの作成方法をおさらいします。ラジオボタンを例に説明しますが、type属性を「checkbox」とすることでチェックボックスでも同じように活用可能です。

inputとlabelを隣接させidとforで紐付けるパターン

文字通り、inputとlabelを隣接させ記述します。
labelタグの「for属性」、inputタグの「id属性」を同じ値にする事で、ラジオボタンとテキストを紐付けます。name属性には、ラジオボタンのグループを特定する名前を指定します。

<input id="apple" type="radio" name="fruits" />
<label for="apple">りんご</label>
<input id="orange" type="radio" name="fruits" />
<label for="orange">みかん</label>
<input id="peach" type="radio" name="fruits" />
<label for="peach">もも</label>

labelを入れ子にするパターン

labelの中にinputを入れる形です。こちらのほうが記述が少なく済むのですっきりしていますね。表示される結果と機能は「inputとlabelを隣接させidとforで紐付けるパターン」と同じです。

<label><input type="radio" name="fruits" />りんご</label>
<label><input type="radio" name="fruits" />みかん</label>
<label><input type="radio" name="fruits" />もも</label>

チェックボックス/ラジオボタンの装飾方法

チェックボックス/ラジオボタンの装飾方法大きく分けて以下の4ステップです。ひとつずつ詳しくみていきましょう。

  1. input要素の非表示化
  2. ボタンの設置スペースをpaddingで作成
  3. 擬似要素を使ってチェックボックス/ラジオボタンの各パーツを作成
  4. 擬似クラスを使って「チェックが入った状態」の装飾

input要素の非表示化

デフォルトで表示されているボタンを非表示にします。
コンテンツの非表示方法でよく使用されるのが「display: none」もしくは「visibility: hidden」ですが、今回はアクセシビリティ低下の要因になるため使用を避けます。
アクセシビリティ低下の要因になる理由は、「display: none」を使用した場合、「input」をtabキーでフォーカスできなくなってしまうからです。

別の手段として「visually-hidden」を使用します。
完全に非表示ではなく、コンテンツを視覚的に隠し、スクリーンリーダーでは読ませるということを実現できます。

日本語の解説付きサンプルコードを以下に引用します。

サンプルコード

.visually-hidden {
  /* コンテンツの流れから切り離す */
  position: absolute;
  /* 誤ったコードに対処するための回避策 */
  white-space: nowrap;
  /* 可能な限り文字サイズを小さくするための処理
   * (スクリーンリーダー中には height と width が 0 のものを無視するため)
   */
  width: 1px;
  height: 1px;
  /* オーバーフローしているコンテンツを隠す */
  overflow: hidden;
  /* 要素サイズを変更しうるプロパティのリセット */
  border: 0;
  padding: 0;
  /* 要素のどの部分が表示されるかを定義するもの */
  /* 古いブラウザでは使用できない */
  clip: rect(0 0 0 0);
  /* 最近のブラウザ用
   * コンテンツを非表示にする設定  */
  clip-path: inset(50%); 
  /* 今現在なぜ-1pxがここで設定されるかは分かっていないそうです。
   * それに加えていくつか問題もあるそうです 
   * (参考: https://github.com/h5bp/html5-boilerplate/issues/1985)
   */
  margin: -1px;
}

引用元:https://frasco.io/writing-css-with-accessibility-in-mind-4fc82b26aecb

上記のスタイルをinput要素に当てた結果が以下です。
想定の通り、アクセシビリティ低下を避けてinput要素を非表示にすることができました。

ボタンの設置スペースをpaddingで作成

「visually-hidden」でinput要素を非表示にすることができましたが、装飾したボタンが入るスペースがありません。
それぞれのlabelにpaddingを付与し、ボタンを入れるスペースを作ります。
スペースを確保したものが以下です。それぞれlabelの左にスペースを作りました。

擬似要素を使ってチェックボックス/ラジオボタンの各パーツを作成

空けたスペースにボタンを設置します。inputは先ほど非表示化したので、labelタグの擬似要素を利用してradioボタンを作成します。
擬似要素・beforeにボタンを作成、擬似要素・afterにチェックが入った状態を作成します。
ここで、擬似要素・afterに { opacity : 0 } を指定し、通常時では非表示にします。該当のボタン選択時に { opacity : 1 } とすることで選択時に表示します。

擬似クラスを使って「チェックが入った状態」の装飾

擬似要素・afterをチェック時に { opacity : 1 }とするために、隣接セレクタと擬似クラスを使用します。
擬似クラスを使用し、タグの特定の状態を指定します。今回の場合であれば、inputに「チェックが入った状態」のcheckedを使います。
隣接セレクタとは、セレクタを + で区切ることで、同じ階層にある要素同士で、 ある要素の直後に隣接している要素を対象にスタイルを適応することができます。こちらは「labelを入れ子にするパターン」の記述では、inputとlabelが同じ階層にないので使えないため、ラベルの文字をspanで囲む等の工夫が必要です。
上記を踏まえ、「チェックが入った状態」のボタンを表示するためには以下のような指定になります。

input:checked + label::after {opacity : 1 ;}

反映し、ボタンを「りんご」選択した結果が以下です。「input:checked」のときに「label::after」の要素が「opacity : 1 」となっています。

装飾のための4ステップを実装したコードは以下です。

<input  class="visually-hidden" type="radio" name="fruits" id="apple"  />
<label for="apple">りんご</label>
<input class="visually-hidden" type="radio" name="fruits" id="orange"/>
<label for="orange">みかん</label>
<input class="visually-hidden" type="radio" name="fruits" id="peach" />
<label for="peach">もも</label>
label {
  position: relative;
  cursor: pointer;
  padding-left: 30px;
}

label::before,
label::after {
  content: "";
  display: block; 
  border-radius: 50%;
  position: absolute;
  transform: translateY(-50%);
  top: 50%;
}

label::before {
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  left: 5px;
}

label::after {
  background-color: #ddd;
  border-radius: 50%;
  opacity: 0;
  width: 16px;
  height: 16px;
  left: 7px
}

input:checked + label::after {
  opacity: 1;
}

.visually-hidden {
 position: absolute;
 white-space: nowrap;
 border: 0;
 clip: rect(0 0 0 0);
 clip-path: inset(50%);
 overflow: hidden;
 height: 1px;
 width: 1px;
 margin: -1px;
 padding: 0;
}

チェックボックス/ラジオボタンの装飾の際のスニペット(サンプルコード)

ここから、いくつかサンプルを紹介します。理解が難しい場合はこちらコピペでも使用可能です。HTMLは共通です。

シンプルなチェックのサンプル

<input  class="visually-hidden" type="radio" name="fruits" id="apple"  />
<label for="apple">りんご</label>
<input class="visually-hidden" type="radio" name="fruits" id="orange"/>
<label for="orange">みかん</label>
<input class="visually-hidden" type="radio" name="fruits" id="peach" />
<label for="peach">もも</label>
label {
  cursor: pointer;
  padding-left: 30px;
  position: relative;
}


label::before,
label::after {
  content: "";
  display: block; 
  position: absolute;
}

label::before {
  background-color: #fff;
  border-radius: 0%;
  border: 1px solid #ddd;
  width: 20px;
  height: 20px;
  transform: translateY(-50%);
  top: 50%;
  left: 5px;
}

label::after {
  border-bottom: 2px solid #ddd;
  border-left: 2px solid #ddd;
  opacity: 0;
  height: 5px;
  width: 10px;
  transform: rotate(-45deg);
  top: 2px;
  left: 10px;
}

input:checked + label::after {
  opacity: 1;
}

カラフルなボタンのサンプル

前章のものとほとんど同じ内容です。CSS内のbackground-colorとborderの色の指定を変更することで自在に色を変更することができます。

label {
  cursor: pointer;
  padding-left: 30px;
  position: relative;
}

label::before,
label::after {
  content: "";
  display: block;
  border-radius: 50%;
  position: absolute;
  transform: translateY(-50%);
  top: 50%;
}

label::before {
  background-color: #fff;
  border: 1px solid #008000;
  height: 20px;
  width: 20px;
  left: 5px;
}

label::after {
  background-color: #008000;
  opacity: 0;
  height: 16px;
  width: 16px;
  left: 7px;
}

input:checked + label::after {
  opacity: 1;
}

トグルスイッチ型ボタンのサンプル

label {
  cursor: pointer;
  position: relative;
  margin-left: 10px;
  padding-left: 50px;
}

label::before,
label::after {
  background-color: #ddd;
  border-radius: 50%;
  transition: 0.3s;
  transform: translateY(-50%);
  top: 50%;
  left: 0px;
}


label::before {
  background-color: #fff;
  border-radius: 10px;
  border: 1px solid #ddd;
  height: 20px;
  width: 40px;
  left: 5px;
}

label::after {
  background-color: #ddd;
  border-radius: 50%;
  opacity: 1;
  height: 22px;
  width: 22px;
  left: 0px;
}

input:checked + label::before {
  background-color: #73e600;
}

input:checked + label::after {
  left: 27px;
}

まとめ

以上がラジオボタン・チェックボックスの装飾方法のご紹介でした。
擬似クラスや隣接セレクタの使用経験がなかった方は、知見が広がったのではないでしょうか。ぜひ、別の機会にも応用してみてください。
自由自在にラジオボタン・チェックボックスを装飾し、より良いユーザー体験を実現できればと思います。

以上、お読みいただきありがとうございました。

この記事の執筆者

Takumi Kitamura

Takumi Kitamura

1995年生まれ。京都府出身。関西の大学を卒業後、ベトナムのオフショア開発企業に就職。その後、サービス事業の立ち上げ、運営に参画し事業の売却を機にフロントエンドエンジニアに転向、キオミルに入社。「運用・改修のしやすさ」を意識した実装を心がけ、webサイト制作に取り組んでいる。趣味は映画鑑賞。

この記事を気に入りましたら、ぜひ「いいね」「シェア」をお願いします。

キオミル株式会社では個別交流会を実施しています。

キオミルでは将来一緒に働いてくれる仲間やパートナー、同業種の方々と交流したいと考えています。転職先や職職先としてキオミルに興味がある方、同業者やパートナーとしてキオミルに興味のある方。まずは飲み物でも飲みながらゆるやかに交流しませんか?

Web制作に関するお悩みがある方はお気軽にご相談ください。

このブログについて

キオミルブログはキオミル株式会社のスタッフが日々の学びや社内のカルチャーなどを発信するブログです。

キオミル株式会社はビジネス課題を解決できるWeb制作会社です。特に中小中堅企業を中心とした、BtoB企業の新規見込客の獲得や採用強化、業務効率化の支援を得意としています。Web制作やマーケティングに関するお悩みがある方はお気軽にご相談ください。