【CSS】input[type=”file”]をCSSだけでカスタマイズする

CSS

概要

ファイルアップロードのための 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>

対象の inputlabeldiv などで囲み、この要素で見た目を整えます。
以下が装飾部分です。見た目はプロジェクトごとに違うと思うのでここはスルーで大丈夫です。

ラッパー要素が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: relativeposition: absolute で余計な隙間ができないようにする
  • opacity: 0 でインプットタグを非表示にする

コメント

タイトルとURLをコピーしました