私がHTML の <select> 要素 multipleに求めること(動くサンプルコードあり)

# HTML の <select> 要素 multiple
## はじめに

まずは下記の画像とマークアップをご覧ください。

<img width="431" alt="スクリーンショット 2019-05-11 18.37.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/0505a758-0df6-6efe-4d36-acf10d260a56.png">

```html:index.html
<div class="box">
  <p>select</p>
  <select name="select1">
    <option value="en">英語</option>
    <option value="de" disabled>ドイツ語</option>
    <option value="fr" selected>フランス語</option>
    <option value="ja">日本語</option>
    <option value="zh">中国語</option>
  </select>
</div>

<div class="box">
    <p>select multiple</p>
    <select name="select2" multiple>
    <option value="en">英語</option>
    <option value="de" disabled>ドイツ語</option>
    <option value="fr" selected>フランス語</option>
    <option value="ja" selected>日本語</option>
    <option value="zh">中国語</option>
  </select>
</div>
```

```css:style.css
.box{
  border: 1px solid;
  margin: 1rem;
  padding: 1rem;
}
```

何の変哲も無いselect要素です。

この記事ではHTMLのselect要素のUIについてもう一度考えてみました。

皆さんもご存知のように上の画像は、選択肢が限られている際に選択するUIとしてWebアプリケーションで頻繁に使う select要素です。

select要素にmultiple属性を与えると上の画像でいうと下のように複数選択が可能なselect要素になります。

## モバイル

私は、モバイルでのselect multipleには不満がありません。

どのように動作するかは下記の画像のようになります。

select要素multiple選択時
<img width="861" alt="スクリーンショット 2019-05-11 18.53.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/cda88cec-e78d-183b-b094-d6dda38aa34c.png">

選択時のインターフェースはandroid,iosで違えど、各OSでのデフォルトのUIなのでそれぞれのユーザーにとって馴染みがあり操作しやすく、多くの方が複数選択も問題なく選択できると思います。

## PC

**PCでの不満点が2つあります。**
それは

- **操作が少し難しい**
- **表示が変わる**

と思っています。

### 操作が少し難しい
複数選択するためには、
複数の選択は`shift`を押しながらクリックで、最後に選択したところからクリックしたところまでの全てを選択します。また、単体で複数を選択する際には
macなら`cmd`+クリック
windowsなら`ctrl`+クリック
になります。もうちょっと簡単だったらいいのに。

### 表示が変わる
`multiple` が指定されている場合、多くのブラウザーは単一行のドロップダウンの代わりに、スクロールするリストボックスを表示します。(単一のselect要素に`size="4"` の属性が付与されているのと同じ表示になります。)
表示に関してはモバイルとPCで問題が発生しそうなポイントですね。

## ライブラリ

こういう時に先人の力を借りるべくライブラリを探すわけです。
自分が使ったことがあり、PCとandroid,iosで確認した複数選択ができるライブラリは下記になります。

- UIライブラリ1: https://materializecss.com/select.html
- UIライブラリ2: https://bulma.io/documentation/form/select/
- React用UIライブラリ: https://material-ui.com/demos/selects/
- Vue用UIライブラリ: https://vuetifyjs.com/ja/components/selects/
- jQueryプラグイン: https://select2.org/

どれも優秀なライブラリーですが、各ユーザーのデバイスでの慣れや一貫性を考えると、モバイルでのネイティブのUIには劣ってしまうなーと感じます。(bulmaに関してはスタイルをつけているだけなので、モバイルはいいけど、PCでの操作と表示の問題が発生します。)



# なぜブラウザのデフォルトUIを求めるのか

見た目にこだわって選択したライブラリが
・思っていたものよりも高機能でコードサイズが大きかった経験ないですか？
・使い心地がPCもしくはモバイルでいまいちだった経験ないですか？
・`O(N^2)`で計算時間が増加しパフォーマンスが劣化した経験はないですか？
・機能性を追求して結局求めていたものはデフォルトのUIだったみたいな経験ないですか？

作るものによるとは思いますが、基本的にかっこいいからとか可愛いからという理由で自分はUIはなるべくサードパーティを使いたくないですね。
各ユーザーのデバイスでの慣れや一貫性をアプリのレイヤーではなくOSのレイヤーで考えるとブラウザのデフォルトのUIで完結している場合も多い思うんです。


また、ブラウザのデフォルトのUIは安定しているし、パフォーマンス的に考えられていたり、キーボードのショートカットがきちんと割り当てられているので、表面上の「映え」よりも結果的にUXに優れています。

デフォルトUIが**見た目的に**嫌いでも、スタイリングすればいいのです。本当にライブラリは必要ですか？
UIフレームワークで最近人気の「Bulma」ってありますがスタイルを変えているだけなので、デフォルトの挙動に対してスクリプトで変なことしてないので好きです。


# どうなってほしいのか(動くサンプルコードあり)

モバイルに関しては不満がないので、PCの場合だけ少し変えてみたいと思います。
先ほどあげたように

- **操作が少し難しい**
- **表示が変わる**

を改善します。

単一の選択肢の際のselect要素をベースに、アクティブになった時に複数選択のリストボックスを表示してみたいと思います。また、クリックすることで選択のオンオフを切り替えられるようにします。

勢いで書いたのでクロームでしか試していません。一応タッチデバイスではデフォルトのUIが出るようにしています。

動作
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204698/09380322-0a11-5c9a-8149-846e263c5294.gif)

コード
https://stackblitz.com/edit/native-multiple-select?file=index.js


# まとめ
・多分ブラウザの下位互換や歴史的にUIが変更されることはないと思うので結局自分でライブラリか何かを作るしかないんだろうねー
・ひさびさにDOMを触って昔を思い出した
・Reactなどでラップして小さいコンポーネント作ろうかなと思った