HTMLのselectにcssで装飾をつける

## はじめに
chrome134から`appearance: base-select`が使えるようになり、selectボックスをcssで装飾ができるようになりました。



:::note warn
2025年4月13日時点でappearance: base-selectが使用できるブラウザは、ChromeとEdgeのみになります。
:::


![appearance: base-selectのcan i useのスクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3443/b5d1cb9c-7631-4ed5-9365-e4417b64965f.png)

## selectボックスを装飾


![画面収録 2025-04-01 1.31.26.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3443/8e7c119e-4c8d-4359-b93e-4ad35ffd1e19.gif)

[Mdnのselectタグ](https://developer.mozilla.org/ja/docs/Web/HTML/Element/select)のサンプルコードを動かした感じのgifアニメーションです。
この動作は皆さんの多くが見たことある挙動だと思います。
では`appearance: base-select`を使った装飾はどういった感じになるのか、以下のgif画像がそうです。
セレクトボックスを開いた時が全く違っています。

![画面収録 2025-04-07 1.31.36.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3443/63f3c497-7ab8-4caa-a05c-7954769ad2d9.gif)


### 実装方法

`selct`タグと`select`タグの疑似要素`::picker()`に`appearance: base-select`を追加するだけです。

:::note warn
疑似要素`::picker()`も、現時点ではChromeとEdgeのみになります。
:::

```css

select, select::picker(select) {
  appearance: base-select;
}
```

CSSはこれだけです。

MdnのHTMLをコピーし、それに対して自分なりにアレンジしたのが以下になります。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="jENmaBm" data-pen-title="Select Style" data-user="makoto-ogata" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/makoto-ogata/pen/jENmaBm">
  Select Style</a> by Makoto Ogata (<a href="https://codepen.io/makoto-ogata">@makoto-ogata</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>



### コードを抜粋

```html

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Material Symbolをインポート -->

<select name="pets-new" class="new">
  <button>
    <selectedcontent></selectedcontent>
    <!-- selectedcontentで選択した要素を保存 -->
    <span class="material-symbols-outlined">
      keyboard_arrow_down
    </span>
    <!-- デフォルトの下矢印ではなく、Material Symbolの下矢印を使用 -->
  </button>
  <optgroup>
    <option value="" hidden disabled selected>--Please choose an option--</option>
    <option value="dog">Dog</option>
    <option value="cat">Cat</option>
    <option value="hamster">Hamster</option>
    <option value="parrot">Parrot</option>
    <option value="spider">Spider</option>
    <option value="goldfish">Goldfish</option>
  </optgroup>
</select>

```

```css
.new {
  appearance: base-select;
  display: block;
  min-width: 300px;
}

.new::picker(select) {
  appearance: base-select;
  border-radius: 8px;
  margin-top: 8px;
}

.new::picker-icon {
  display: none; /* デフォルトの下矢印を非表示 */
}

option::checkmark {
  font-family: 'Material Icons';
  content: '\e8dc';
  color: red;
}

button {
  display: flex;
  width: 100%;
  
  > span {
    margin: 0 0 0 auto;
    
  }
}
```

上記のコードで`appearance: base-select`や`::picker()`以外にも、いくつか見慣れない疑似要素やHTMLタグがあるかと思います。

### ::picker-icon

セレクトボックスの右端にある下矢印の箇所です。
私が書いたCSSでは`display:none`にして、その代わりにMaterial Symbolで表現してます。

https://developer.mozilla.org/en-US/docs/Web/CSS/::picker-icon


### ::checkmark

どの`option`タグが選択されているかを視覚的に示すために使用します。
MDNにも書いてあるように、`content`で生成されたアイコンは読み上げられないので、アクセシビリティ的に注意が必要みたいです。

https://developer.mozilla.org/en-US/docs/Web/CSS/::checkmark

## 最後に
selectもようやくスタイルを当てる事が可能になって、表現の幅が広がってきました。
早く全てのブラウザで実装できる様になって欲しいと思います。



## 参考

https://developer.chrome.com/blog/rfc-customizable-select?hl=ja

https://developer.chrome.com/blog/a-customizable-select?authuser=9

https://azukiazusa.dev/blog/customizable-select-element/

https://dev.to/link2twenty/future-of-css-select-styling-without-the-hacks-38c2