概要
ファイルアップロードのための input
をカスタマイズしたいけれど、JSを使うのは面倒だし、
でも label
でラップするのはドラック&ドロップが効かなくなる。::file-selector-button
は「選択されていません」が消えないし…
ということでちょっと誤魔化し感がありますが、JSを使わず、ドラック&ドロップも効かせたまま、「選択されていません」のテキストも見えないようにするやり方をご紹介します。
結論
以下のような感じのインプットができます。

<div class='file_input_wrapper'>
<input type='file' name='file' id='file' accept='image/*' class='file_input'>
</div>
.file_input_wrapper {
display: flex;
justify-content: center;
align-items: center;
position: relative; /* 上に被さるようにします */
width: 400px;
height: 200px;
border: solid 1px #333333;
border-radius: 4px;
}
.file_input {
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0; /* ←ここがポイント */
}
解説
<div class='file_input_wrapper'>
<input type='file' name='file' id='file' accept='image/*' class='file_input'>
</div>
対象の input
を label
や div
などで囲み、この要素で見た目を整えます。
以下が装飾部分です。見た目はプロジェクトごとに違うと思うのでここはスルーで大丈夫です。
ラッパー要素がinputに被さるようにするため、 position: relative;
だけはマストで設定してください。
.file_input_wrapper {
position: relative; /* このラッパーが上に被さるようにこの設定はつけてください */
display: flex;
justify-content: center;
align-items: center;
width: 400px;
height: 200px;
border: solid 1px #333333;
border-radius: 4px;
}
インプットは opacity
で非表示にします。
※ display: none
で設定してしまうとドラック&ドロップが効かなくなってしまいます。
.file_input {
position: absolute; /* ラッパーの内側に入るようにしてください */
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0; /* ←ここがポイント */
}
インプットタグがラッパー要素の大きさと同じになるようにすると、反応しない部分がなくなって良いと思います。
まとめ
ポイントは3つです。
input
を他の要素でラップするposition: relative
、position: absolute
で余計な隙間ができないようにするopacity: 0
でインプットタグを非表示にする
コメント