471 文字
2 分

余計なDOMを追加せずにinput[type="file"]を装飾する

2024-02-13

::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/
作者
hrdtbs
公開日
2024-02-13
ライセンス
CC BY-NC-SA 4.0