Wednesday 9 October 2013

How to make a nice file upload button with HTML & CSS

We have all seen the horrible file upload boxes, we all know what they look like.. and they all differ slightly from browser to browser.

There are lots of hacks out there to emulate a button click to launch the file input dialog, or to position the input box transparent ontop of a beautified button, but all of these are limited to the browser support and some browsers require hacks.

I want to show you the simplest way I can think of..

Here's how it looks:




Ok that's cool, but how exactly does it work?



<style>
.upload_box {
    overflow:hidden;
    position:relative;
}

#select_file {
    position:absolute;
    left:-300px;
}

label {
    cursor:pointer;
    font-weight:bold;
}
</style>
<div class="upload_box">
    <input id="select_file" type="file" />
    <label for="select_file" id="selected">To select your file click here!</label>
</div>
>And that's all there is to it.. Let me explain.. the good thing about the label tag is it links to the input element that you would like to focus on.. the container ( .upload_box ) has the css attribute overflow:hidden; so we basically hide the input element off to the left, which essentially "hides" the input element, so when you click on the label, it triggers the input dialog. Because this is a label, you can style it to however you like.. this is how I have styled it for one of my clients:






So, now we've covered how to do it.. there's one more thing you should know, once you select the file it won't display the file name, so to do this we do need a small piece of Javascript.. This is the Javascript:


<script>
function fileName()
{
  var _file = document.getElementById('select_file');
  document.getElementById('selected').innerHTML = _file.value.replace(/C:\\fakepath\\/i, '');
}
</script>

To make this work, you need to attach fileName() to the input field, to do this simply add onchange="fileName()" like so:


<input id="select_file" type="file" onchange="fileName()" />

I hope this has helped!

And here's a working DEMO