Customize File upload control

Unlike other form controls such as textbox, checkbox or radio button, you'll find it hard to customize file upload control. The look and feel of this control is totally managed by the rendering browser. A simple customization like changing the button color or remove the text "Choose a file" seems to be impossible. However, I am sure you have seen several plugins or libraries magically using their own UI to upload file. How did they do that?

In this post, I am going to introduce to you a technique which allow you to create your own file upload control with its own look and feel. And this technique is used commonly by uploading plugins you see on the Internet.

In my experience, no matter how you want to customize the file upload control, the <input type='file'> is required to be present somewhere in your HTML document. The fundamental idea of my method is that we are going to show users something else instead of this original control. The original <input> tag is still there but we will make it not visible from users.

First of all, I am going wrap the <input> tag inside a <button> tag. The <button> tag will become our customizable file upload control.

<button id="fileupload">
    <input type="file" name="file" />
</button>

And then, we will apply a little CSS to our HTML

#fileupload{
    background-color: green;
    height: 30px;
    width: 200px;
    color: white;
    font-size: 18px;
    position: relative;
}

input[name=file]{
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
}

I set the input to fully cover the button tag because I want to make sure that user can click on any place inside the div to see the upload action. Until now, the only problem is the <input> tag is still visible to users. This can be easily fixed using opacity property

input[name=file]{
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    opacity: 0;
}

It would be event better if you use cross browser CSS for opacity property

  /* IE 8 */
  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";

  /* IE 5-7 */
  filter: alpha(opacity=0);

  /* Netscape */
  -moz-opacity: 0;

  /* Safari 1.x */
  -khtml-opacity: 0;

  /* Good browsers */
  opacity: 0;

It looks much cooler now, right? A nice, customizable button instead of hard-looking file upload control. But wait, after selecting a file, remember that you need to show users what file they have selected. I will add another div just to show the selected file name.

<button id="fileupload">
    Upload file
    <input type="file" name="file" />
</button>
<div id="file-name"></div>

And I am going to handle the change event of input control like this

$("input[name=file]").change(function(){
    var file = $(this).val();
    $("#file-name").text(file);
});

Check out jsFiddle: https://jsfiddle.net/h6sqo06e/

I believe this is one of the easiest way to customize the <input type="file"/> control without spending much time on handling other events.

Happy coding!