471 文字
2 分
余計なDOMを追加せずにinput[type="file"]を装飾する
::file-selector-button
が利用することで、input[type="file"]
を装飾することが出来る。
しかし::file-selector-button
疑似要素は、2021 年時点で全てのモダンブラウザでサポートされたが、あまり利用されているイメージがない。
https://developer.mozilla.org/en-US/docs/Web/CSS/::file-selector-button
実装例
次のように装飾することが出来る。
<div> <style> input[type="file"] { border: 2px dotted #cbd5e1; padding: 16px; background-color: #f1f5f9; border-radius: 8px; cursor: pointer; transition: 0.2s ease-out; &::file-selector-button { background-color: white; border: 1px solid #ff7f50; line-height: 24px; cursor: pointer; color: coral; font-weight: bolder; padding: 12px 16px; border-radius: 16px; margin-inline-end: 16px; transition: 0.2s ease-out; } &:hover { border-color: #a6c1e0; &::file-selector-button { color: #ff5b1f; border-color: #ff5b1f; } } } </style> <input type="file" /></div>
余計な DOM を追加する手法との比較
Pros
- File input 本来のアクセシビリティの恩恵をそのまま受けられる。
- 余計な DOM を追加して実装する場合、考慮するべきことが多い。
- input 要素を display: none などで隠すと、required などが効かなくなる。
- label 要素で外見を作ってしまうと、クリックイベントなどを発火出来なくなる。
- 実装に依るが input 要素自体に元々あるドラッグ&ドロップ機能を自前で実装する必要がある。
Cons
- コンテンツの位置調整が困難。
::file-selector-button
と文字列を子要素のように扱えるわけではないため、input 要素を Grid や Flexbox にして位置を調整することは出来ない。position や float などのプロパティは効く。
- 入力要素の文章を差し替えることは出来ない。
- 無理やり消して、
::before
や::after
で挿入することは出来るが、アクセシビリティの観点からも推奨できない。
- 無理やり消して、
余計なDOMを追加せずにinput[type="file"]を装飾する
https://blog.ohirunewani.com/posts/input-type-fil-decorate-by-file-selector-button/