技術とかの雑なToday I Learnedメモ

labelでinput[type="file"]を装飾する話の記事

labelでinput[type="file"]を装飾する話の記事

label で input[type="file"] を装飾するな

読んだ。

ひとまずlabelで装飾しているところがないか手元のコードを確認したけど、コンポーネントライブラリを使っていたりしてひとまず大丈夫そうだった。

問題は

  • フォーカスが当たらない
  • tabIndexを設定してもlabelはclickableではないのでSpace/Enterでclickイベントを発火させられない

のふたつ。

解決策は、

  • button要素を用意する
  • そのbuttonのclickイベントに、input要素のclickイベントを発火させる関数を定義する
  • button要素が適切でない場合にはアクセシビリティに配慮したボタンを用意する
<div role="button" tabindex="0">ファイルを選択</div>
<input type="file" />

↑記事内のコードを引用

miyaokaさんのやり方↓

labelを使うやり方で、input要素をdisplay: none;にするのではなく

.input {
  opacity: 0; /* 要素は完全に透明で不可視 */
  pointer-events: none; /* 要素がポインターのイベント対象にならない */
}

のようにして、clickイベントは発生しないがtabでのフォーカスをできるようにし、:focus-withinでフォーカス時のスタイルを調整しているという感じらしい。

こうすることで、button要素の追加やclickイベントを発火する関数の定義をしないでCSSだけでいけるのか、なるほど。

ウェブアプリケーションからのファイルの使用 - Web API | MDN

opacity - CSS: カスケーディングスタイルシート | MDN

pointer-events - CSS: カスケーディングスタイルシート | MDN

:focus-within - CSS: カスケーディングスタイルシート | MDN