After reading about Brian McKellar’s challenge in Craig Cmehil’s weblog INPUT TYPE=”FILE” and your options… , I remembered that this has annoyed me as well for some time, and set out to investigate the possibilities.
For those who do not know the problem, the image below will illustrate it. The browse button beside the file input field is mandatory, and unlike most other HTML elements there is no style attribute you can apply to it.
There is no spoon
A lot of people would have taken it for granted that there was no way of changing the appearance of this button, but watching the matrix a few times lead me to believe otherwise. Just as there is no spoon, there is no way to change the appearance of the browse button. Untill, you’ve realized this you cannot succeed.
Let us assume there is a standard style attribute attribute on the file upload input element (although we know there really isn’t). Then the following code should be able to change its appearance:
The code basically defines a CSS class and assigns it to an input field (which must be inside a form element).
Close, but no cigar
Since we know we can’t change the browser button’s style, we might as well add a new to the form and change the style on that. Adding the button on top of the file upload browse button, would hide its ugliness. We can use relative placing on a span element to achieve this.
Although it would probably look better now, the file upload doesn’t work anymore as we only press the new button and not the browse button which opens up the file dialog. Couldn’t we say that if the button was clicked, it again should tell the browse button that it was clicked? Doing this, we end up with the following code:
The line of code that does most of the work is document.forms[‘myForm’].myFile.click(). It basically says that in the form myForm, the element myFile should simulate a mouse click. Unfortunately, this only works in IE and not really here either. Allthough the file dialog comes up, and the filename is placed in the input field, once you push submit the field is blanked out and the form is never sent. This is probably the same code that Brian once tried to ship in the service pack.
The actual solution
It seems like it actually is possible to assign a style to the
What we do is to create a fake dummy form which is in the background (use the z-index css attribute for layer order). It contains a text field and the button/image we would like for the upload. When the user clicks the “fake” button, the user actually hits the file upload browse button and the file dialog is shown. To be more user friendly we read the file name from the invisible file upload field and add it to the “fake” input field. We’ve also replaced the button we used in the previous examples with an image. The actual code for all this is shown below:
style=”position: absolute; top: 10px; left: 10px;z-index: 1;”>
style=”position: absolute; top: 10px; left: 10px; z-index: 0;”>
For a working example you can go to http://temp.elsewhat.com (this site might not be up, as it is running on my computer which tends to crash every now and then). A screen shot of the example is provided below:
There are some limitations to this solution:
- It only works in browser supporting opacity, not in for example IE 5.0. In IE 5.0 the fall-back solution will be that both layers are displayed, but the file upload will be on top and will at least partially cover the fake form.