こんにちは、ryohei(@ityryohei)です!

本記事では、ファイルをアップロードする際に使用する「input type=”file”」を好みのデザインにカスタマイズする方法をご紹介しています。

端末のスペックやインターネットの速度が上がるにつれて、画像や動画のようなメディアファイルを取り扱うサイトやWebアプリケーションが随分と増えてきました。大手SNSはもちろん、個人開発のサービスでもそれは顕著に思われます。

それに、2020年は5Gが解禁されます。5Gの普及に伴いメディア、特に動画のような大容量のファイルを取り扱うことが増えていくと予想されるため、ファイルを取り扱う処理を構築する機会も増えていくのかな、とか勝手に思っています。

と、全く本題と関係ない方向に話が逸れてしまいましたが……

本記事でご紹介するのはファイルをアップロードする際に使用する「input type=”file”」のデザインをカスタマイズする方法になります。デフォルトだと無機質で味気ない感じですが、デザインをカスタマイズする方法がわかれば、デフォルトでは気に入らないボタンを、自分好みに変身させることができます。

では、解説していきます。

まずはデフォルトの「[input type=”file”」を作って確認してみよう

inputのtype属性にはフォームの項目を簡単に実装することがができるアイテムがたくさん用意されています。その中の一つが「file」です。inputのfileは、その名称の通りにファイルを取り扱うことができるするための値になります。

指定方法は簡単です。下記のようにtype属性にfileを指定するだけです。

HTML

<input type="file" name="file">

上記のコードをHTMLのファイル内で実行すると下記のようなアイテムが画面上に表示されます。

See the Pen
Customize Input File1 | jQuery+CSS
by ryohei (@intotheprogram)
on CodePen.

実際に「ファイルを選択」と表示されたボタンをクリックすると、Windowsであればエクスプローラーが、MacであればFinderのようなUI上でファイルを選択することができるウィンドウが表示されます。(FIleChooserのようなイメージです。)

ただ、簡単に実装できることができる反面、見ての通りデザインはあまりよくないです。デザイナーの方が発見したならば、すぐに修正指示を出すような見た目です。なので、この状態から好きなデザインにカスタマイズしていきます。

いったんinput要素を非表示にする

カスタマイズをするために、まずは作成したinput要素には画面内から消えてもらいます。記述自体は残した状態にしておき、CSSで見えないようにする、といった意味合いになります。

要素を見えないようにするプロパティはいくつかありますが、今回はオーソドックスな「display: none」を使用することにします。

HTML

<input type="file" name="file">

CSS

input[type="file"] {
    display: none;
}

非表示するスタイルを適用すると下記のように非表示になります。

See the Pen
Customize Input File2 | jQuery+CSS
by ryohei (@intotheprogram)
on CodePen.

これで準備が整いましたので、早速カスタマイズしていきましょう!

input要素をlabel要素で囲んでスタイルを付ける

前項で非表示にしたinput要素をlabel要素で囲みます。このlabel要素にスタイルを付けてボタンのようにしていきます。せっかくなので、ボタンのテキストも一緒に記述しておきましょう。

HTML

<label>
    <input type="file" name="file">ファイルを選択
</label>

スタイルの定義はお好みで。サンプルでは簡単に背景を付けるだけにしておきます。input要素は非表示にしたままで大丈夫です!

CSS

label {
    padding: 10px 40px;
    color: #ffffff;
    background-color: #384878;
    cursor: pointer;
}

input[type="file"] {
    display: none;
}

更新すると下記のような表示に。クリックするとちゃんとウィンドウが表示されます。簡単なスタイルですが、随分とボタンらしくなりましたね!

See the Pen
Customize Input File3 | jQuery+CSS
by ryohei (@intotheprogram)
on CodePen.

ただ、上記のデモには足りないものがあります。それはファイルの選択状態を表すテキストです。ファイルが選択されていなければ「選択されていません」という表示が、選択されたらファイル名が表示されます。

input type=”file”」には必要なものですので、こちらも追加していきます。

ファイルの選択状態を表示する要素を追加する

ファイルの選択状態を表示する要素に、今回は「p要素」を使用します。中にはページ読み込み時に表示しておきたいテキストを指定しておきます。

HTML

<label>
    <input type="file" name="file">ファイルを選択
</label>
<p>選択されていません</p>

余白が詰まっていると見にくいため、マージンだけ指定しておきます。

CSS

label {
    padding: 10px 40px;
    color: #ffffff;
    background-color: #384878;
    cursor: pointer;
}

input[type="file"] {
    display: none;
}

p {
    margin: 10px 0 0 0;    
}

ページを更新すると下記のようなサンプルの表示になります。実際に操作してみましょう。

See the Pen
Customize Input File4 | jQuery+CSS
by ryohei (@intotheprogram)
on CodePen.

上記はテキストを表示しているだけなので、実際にファイルを選択してもファイル名が表示されることはありません。内部的にファイルが選択された状態になっていますが、それがユーザーに伝わらない状態です。非常にまずいです!

なので、実際に選択したファイル名が出力されるように簡単にスクリプトを作成していきます。

選択したファイルのファイル名を出力する

HTMLとCSSに変更はないので、ここでは追加するスクリプトだけ記載しておきます。jQueryを使用していますので本体の読み込みも忘れないようにしましょう。

下記は実際に使用するスクリプトです。処理内容としては、「input要素」に変更があった場合にファイルの情報を取得して、その中のファイル名の情報を「p要素」に出力するようにしています。

JS

$('input').on('change', function () {
    var file = $(this).prop('files')[0];
    $('p').text(file.name);
});

デモを操作していたければと思いますが、ファイルを選択すると実際にファイル名が出力されていますね!

See the Pen
Customize Input File5 | jQuery+CSS
by ryohei (@intotheprogram)
on CodePen.

最後に

input要素のtype属性には多くの値があり、それぞれ用途が異なりますが、その中でもfileは特に扱うことが増えていくと予想されます。見た目のカスタマイズももちろんですが、WebAPIのFileの仕様を把握しておくことも大事になってきまので、早い段階で理解しておくと良いかもしれません。

以上、CSSとJSでinput type=”file”を好みのデザインにカスタマイズする方法のご紹介でした!