Styling a 'file' form field using CSS and Javascript
Saturday 27th March, 2010
I wanted to change the appearance of a html file input element, and as there is no easy way (if at all) of doing this through CSS I had a quick look around google to see what others had to say about the matter.
The websites that kept being mentioned were http://www.quirksmode.org/dom/inputfile.html and http://www.shauninman.com/archive/2007/09/10/styling_file_inputs_with_css_and_the_dom - both working solutions, but it struck me that they were a little cumbersome for what should be such a simple task. Perhaps they are both more backwards compatible and scaleable, but as far as I'm concerned it's no longer necessary to accomadate people using IE4 or Netscape 3, and people normally only have 1, maybe 2 file input fields per page - and as such the following pared down solution should work perfectly.
Tested on:
IE6
IE8
Firefox 3.6.2
Safari 4.03
(all PC)
The only HTML you need is:
<input type="text" id="textinput" />
<div class="file_input_container">
<input type="file" id="uploader" class="file_input" onchange="updateText('textinput')" />
</div>
One standard text input field and a file input field wrapped in a div.
Each input element has its own ID, and the file input has an onchange event which calls a javasript function, sending the name of the relevent text input field.
We then need to apply some CSS to these fields
.file_input_container {
overflow:hidden;
background-image:url(path/to/image.png);
width:150px;
height:50px;
}
.file_input {
width:150px;
height:50px;
opacity:0;
/* Fix for IE */
position:relative;
filter: alpha(opacity = 0);
}
The input container div needs a background image - this should be the custom button image you have created - we then set the size of the div to the same size as the button image and finally set the overflow to 'hidden'.
The file input itself is then set to the same size as the containing div and given an opacity of 0. Note: display:none will not work here as the element has to be clickable. It is also set to position relative so the filter will work in IE.
Finally, a very simple bit of javascript to show the user what file they will be uploading:
function updateText(id) {
// get file name
filename = document.getElementById('uploader').value;
// IE sometimes adds the string 'C:\fakepath\' to the beginning of the file name, this code just checks for that and removes it if it is present
finalfile = filename.replace("C:\\fakepath\\", "");
// Finally, copy the file name string in to the text input field (referenced by the ID sent in the function call)
document.getElementById(id).value = finalfile;
}
Issues
The only problem I have found is that firefox is a little restrictive on the reszing of file input fields, so if your custom button is fairly tall it may only be clickable in the middle region.