【CSS】疑似要素を使ってオリジナルなデザインのフォームを作る

#はじめに
サービスを作る際にフォームのcssをそのままにしているとブラウザ毎にデザインが変わってきてしまうので、afterやbefore等の疑似要素を使ってブラウザに左右されないフォームを作成します。
コピペで終わらないようにコメントでなるべくわかりやすく対応している箇所を書いています。

##ラジオボタン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425289/86412860-9817-60de-04a4-3b4bbe4d1244.png)

```html:HTML
<div class="form">
  <p>果物の種類</p>
  <div class="inputs">
    <div>
      <input type="radio" name="type" id="type1" value="1" checked="checked">
      <label for="type1">りんご</label>
    </div>
    <div>
      <input type="radio" name="type" id="type2" value="2">
      <label for="type2">みかん</label>
    </div>
    <div>
      <input type="radio" name="type" id="type3" value="3">
      <label for="type3">ばなな</label>
    </div>
    <div>
      <input type="radio" name="type" id="type4" value="4">
      <label for="type4">いちご</label>
    </div>
  </div>
</div>
```

```css:css
.form .inputs div {
    margin: 10px;
}
.form .inputs div input[type="radio"] {
  /* 既存のラジオボタンを非表示に   */
    display: none;
}
.form .inputs div input[type="radio"] + label {
  /* ラベル全体がクリック適用範囲だとわかるように */
    position: relative;
    cursor: pointer;
    display: flex;
    font-size: 20px;
}
.form .inputs div input[type="radio"] + label::before {
  /* コンテンツの作成 【外円】*/
    content: "";
    position: relative;
    box-sizing: border-box;
    width: 30px;
    height: 30px;
    background: #FFF;
    border: 1px solid #000;
  /* 円状に */
    border-radius: 50%;
    margin-right: 10px;
}
.form .inputs div input[type="radio"]:checked + label::after {
  /* コンテンツの作成 【内円】*/
    content: "";
  /* 位置をbeforeにそろえる */
    position: absolute;
    left: 5px;
    margin-top: 5px;
    box-sizing: border-box;
  /* チェックは外円より小さく */
    width: 20px;
    height: 20px;
    background: orange;
  /* 円状に */
    border-radius: 50%;
}
```
もとのラジオボタンは非表示にしているので、要素をlabelで囲むか、labelにfor属性を追加し、値にラジオボタンのID値を指定しないとクリックしても反応してくれないので注意。

##チェックボックス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425289/ab5e95f0-a199-0754-5c29-3e620755c4ad.png)

```html:HTML
<div id="form">
  <div>
    <label><input type="checkbox" name="check1" id="check1" value="1">チェック１</label>
  </div>
  <div>
    <label><input type="checkbox" name="check2" id="check2" value="2">チェック２</label>
  </div>
</div>
```

```css:css
#form div {
    margin: 10px;
}
input {
  /* 元々のチェックボックス（今回は消さない） */
    width: 40px;
    height: 40px;
    position: relative;
    margin-right: 10px;
}
input::before {
  /* コンテンツの作成 【外箱】*/
    content: '';
  /* 既存のチェックボックスに被せる形で */
    position:absolute;
    width: 36px;
    height: 36px;
    background: #fff;
    border: solid 2px #000;
}

input:checked::after {
  /* コンテンツの作成 【チェック本体】*/
    content: '';
  /* 位置をbeforeにそろえる */
    position:absolute;
    left: 15%;
    top: 20%;
  /* チェック本体左側（左） */
    border-left: 5px solid #fa9a1d;
  /* チェック本体右側（下） */
    border-bottom: 5px solid #fa9a1d;
  /* 上で作成した箱を左45度回転 */
    transform: rotate(-45deg);
  /* 右側（下）長さ */
    width: 23px;
  /* 左側（左）長さ */
    height: 13px;

}
label {
    font-size: 20px;
    line-height: 40px;
    display: flex;
}
```
元のフォームを非表示にせず隠れるような形で疑似要素を作成。

##セレクトボックス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425289/46feb8e0-c860-4ce5-6122-6ca9cf58615f.png)

```html:HTML
<div id="form">
  <label for="fruit">好きなくだもの</label>
  <div class="content">
    <select name="fruit" id="fruit" class="inputs">
      <option selected value="">選択してください</option>
      <option value="1">りんご</option>
      <option value="2">みかん</option>
      <option value="3">ばなな</option>
      <option value="4">いちご</option>
    </select>
    <span class="icon"></span>
  </div>
</div>
```

```css:css
label {
    font-size: 20px;
    padding: 12px;
}
.content {
    padding: 12px;
}
.inputs {
  /* セレクトフォーム本体 */
    border: 2px solid orange;
    width: 280px;
    height: 60px;
    padding-left: 22px;
    font-size: 20px;
    line-height: 27px;
  /* 矢印が裏側に回っているので透明に */
    background-color: transparent;
  /* 既存の矢印マークを非表示に */
    -moz-appearance: none;
    -webkit-appearance: none;
    appearance: none;
}
.icon{
    position: absolute;
  /* 矢印がクリックに反応しないのでフォームの裏側に配置 */
    z-index: -2;
}
.icon::after {
    content: "";
  /* 位置をform内にそろえる */
    position: absolute;
    left: -44px;
    top: 14px;
  /* 上で作成した箱を左45度回転 */
    transform: rotate(-45deg);
  /* 右側（下）長さ */
    width: 20px;
  /* 左側（左）長さ */
    height: 20px;
  /* チェック本体左側（左） */
    border-left: 3px solid orange;
  /* チェック本体右側（下） */
    border-bottom: 3px solid orange;
}
```

#まとめ
フォームのデザインを作成する際に、似通ったものを毎回調べるよりも疑似要素の仕組みを理解した上で、自分で作成するとフォームデザインがブラウザに左右されないだけでなく、デザインの自由度が増し、制作スピードも上がると思います。

問題はフォームの代わりとなるデザインを疑似要素で作成する所だと思いますが、

どれも元となっているフォームを見えないようにし、代わりのものを疑似要素で作成するといった流れになっているので一度手順を掴むと2回目以降楽になるはず・・・多分。