【CSS】フォームのセレクトボックスに角丸などのスタイルを適用する

# 概要
フォーム要素の`<select>`のスタイルを変更するため、元のスタイルを非表示にしてからスタイルを適用した。元のスタイルを表示しない場合矢印も消えるため、独自の矢印を表示する方法もあわせて調べた。

デフォルトの`<select>`は以下のようになる。

```html:HTML
<select name="sample" id="select" class="select">
  <option value="" default></option>
  <option value="1">option1</option>
  <option value="2">option2</option>
  <option value="3">option3</option>
</select>
```
![スクリーンショット 2020-02-18 11.24.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/1d6c0324-42f0-5961-aee3-f1d8f470da85.png)![スクリーンショット 2020-02-18 11.24.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/ee3b8cab-117a-def5-0c56-a89a9f037f7c.png)


# そのままスタイルを変更してみる
デフォルトのスタイルから、

- 幅・高さ
- 枠線の色や太さ・角丸
- 背景色
- 文字の色や大きさ

を変更してみる。

```scss:SCSS
.select {
  width: 150px;
  height: 50px;
  border: 3px solid #FF0000;
  border-radius: 20px;
  background-color: #FFFF00;
  color: #0000FF;
  font-size: 20px;
}
```
　　　　　←Chrome　Firefox→
![スクリーンショット 2020-02-18 11.31.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/c30faa64-4c3a-7422-1fd5-154d3a2735cf.png)![スクリーンショット 2020-02-18 11.31.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/3af05c7b-5a3d-df18-009e-c49a16fbef3f.png)

Chromeの場合は角が`border-radius`で指定した値になっていない（他の値を指定しても変わらず）。
Firefoxでは、矢印部分が違和感のあるスタイルになってしまう。

# `<select>`のスタイルを消す
そこで、元々の`<select>`のスタイルが表示されないようにして、その上から好きなスタイルを適用することにする。
`appearance: none;`を指定することで元々のスタイルを無効にできる（ベンダープレフィックスが必要）。

```scss:SCSS
.select {
  &::-ms-expand {
    display: none; // IE
  }

  -webkit-appearance: none; // Chrome, Safari (Firefoxでも効いた)
  -moz-appearance: none; // Firefox
  appearance: none;

  border: 3px solid #FF0000;
  border-radius: 20px;
  width: 150px;
  height: 50px;
  background-color: #FFFF00;
  color: #0000FF;
  font-size: 20px;
}
```
　　　　　←Chrome　Firefox→
![スクリーンショット 2020-02-18 12.16.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/82e8c5d7-b781-43a7-32da-899b9d5f716b.png)![スクリーンショット 2020-02-18 12.17.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/14c54ecf-44bc-a9e7-3e0c-55b3eaba2b89.png)

これで、意図したスタイルを適用できるようになった。

# 再び矢印を表示する
元々のスタイルを打ち消したことで、矢印が表示されなくなり、セレクトボックスかどうか少し分かりづらくなった。そこで、改めてそれっぽい矢印を表示することにする。
[`::before`](https://developer.mozilla.org/ja/docs/Web/CSS/::before)や[`::after`](https://developer.mozilla.org/ja/docs/Web/CSS/::after)で作成するのが簡単だが、`<select>`には追加できない。そのため、`<div>`等で`<select>`を囲み、その`<div>`に擬似要素を追加する。

```scss:SCSS
.select-container { // div要素
  overflow: hidden;
  position: relative; // ::before要素をabsoluteで表示するため

  &::before {
    position: absolute;
    top: 50%;
    right: 15px;
    transform: translateY(-50%);
    content: "▼"; // これだけでもそれっぽい下三角矢印にできる
  }

  border: 3px solid #FF0000;
  border-radius: 20px;
  width: 150px;
  height: 50px;

  .select {
    width: 100%;
    height: 100%;

    &::-ms-expand {
      display: none;
    }

    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    
    background: #FF0000;
    border: none; // noneにしないと見えてしまう
    padding: 0 20px;
    color: #0000FF;
    font-size: 20px;
  }
}
```
![スクリーンショット 2020-02-18 13.02.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/170cafc5-8cb9-6aa4-75b4-c77b0b424ae3.png)

`<select>`の`width`や`height`を指定しない場合、以下のようになってしまう。
![スクリーンショット 2020-02-18 13.07.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/87f0ab02-407c-de0c-5f31-b22beb503dfd.png)


## `border`で三角を作る
`::before`や`::after`の`border`を利用して、矢印を表示してみる。
要素の`width`・`height`を0にして`border`を表示すると、以下のように三角ができる。

```scss:SCSS
  &::before {
    position: absolute;
    top: 50%;
    right: 15px;
    transform: translateY(-50%);
    content: "";
    width: 0;
    height: 0;
    border-top: 15px solid #555555;
    border-left: 15px solid #FF00FF;
    border-right: 15px solid #ABCDEF;
    border-bottom: 15px solid #000000;
  }
```
![スクリーンショット 2020-02-18 13.23.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/20537ae3-9614-8482-764e-b8eae47bc6d6.png)


これを利用して、下三角矢印を表示する。

```scss:SCSS
.select-container {
  &::before {
    position: absolute;
    top: 50%;
    right: 15px;
    transform: translateY(-50%);
    content: "";
    width: 0;
    height: 0;
    border-top: 15px solid #555555;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
  }
}
```
![スクリーンショット 2020-02-18 13.15.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/86425831-12f7-0155-08d7-8ba485ceb6ff.png)


2つ組み合わせて上下矢印を作成することもできる。

```scss:SCSS
.select-container {
  &::before {
    position: absolute;
    top: 27%;
    right: 15px;
    content: "";
    width: 0;
    height: 0;
    border-bottom: 10px solid #00FF00;
    border-left: 7px solid transparent;
    border-right: 7px solid transparent;
  }
  
  &::after {
    position: absolute;
    top: 54%;
    right: 15px;
    content: "";
    width: 0;
    height: 0;
    border-top: 10px solid #00FFFF;
    border-left: 7px solid transparent;
    border-right: 7px solid transparent;
  }
}
```
![スクリーンショット 2020-02-18 13.12.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/75cc7c41-ffef-5e5f-07eb-6dbb547d3a92.png)


## 矢印部分をクリックできるようにする
現状では、矢印部分をクリックしても`<select>`が反応しない。
![select-pointer.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/6d5d801d-2445-0a38-5d9e-5bed2d14f563.gif)
そこで、`pointer-events: none;`を指定して擬似要素のクリックを無効にする。

```scss:SCSS
.select-container {
  &::before {
    position: absolute;
    top: 50%;
    right: 15px;
    transform: translateY(-50%);
    content: "▼";
    pointer-events: none;
  }
}
```
![select-pointer-ok.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/328b0908-c301-201c-a478-1f782ce90f24.gif)
矢印部分もクリックできるようになった。

# まとめ
- `appearance: none;`で元の`<select>`のスタイルを表示しないようにして、新たにスタイルを適用した。
- 擬似要素で矢印を表示した。

最終形態
<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="css,result" data-user="mmmmmmk" data-slug-hash="dyoXYJz" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="select">
  <span>See the Pen <a href="https://codepen.io/mmmmmmk/pen/dyoXYJz">
  select</a> by mmmmk (<a href="https://codepen.io/mmmmmmk">@mmmmmmk</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 参考
https://copypet.jp/797/