Fancy File Inputs with Mootools and CSS
God, I hate HTML DOM FileUpload Objects (<input type="file"> elements). They're displayed differently by every browser, and it's always ugly. Let's use some fancy AJAX and CSS to fix these horrible, horrible form objects.
Some time ago, we were working on a website that required a contact form with the ability to attach a file. This sounds like, at this point in web design, it should be incredibly simple. Imagine my chagrin as I learned that, in fact, styling the FileUpload Object had a smack of Holy Grail-ness to it. Well, at least as far as HTML form objects are concerned.
A lot of people have had similar ideas on how to handle this. I suppose it all started with Michael McGrady’s solution, which was followed closely by an improvement on McGrady’s technique from Peter-Paul Koch over at Quirksmode. The closest thing I found to a satisfactory solution, though, came from Shaun Inman. His solution was definitely the right idea, but it wasn’t exactly full-featured, and I wanted it built in my favorite Javascript framework.
Like Shaun, I don’t think that the text-box is an appropriate UI element for a file upload in 2008 (who wants to type c:\Documents and Settings\Paul\My Documents\My Photos\2008-06-02-Me.jpg into a field that only shows 25 characters?!). Further, every implementation I’ve ever seen that makes use of a text-box is wonky. So I wanted to do a Safari-style upload.
Shaun’s really clever idea involves setting the input’s opacity to zero and then using a little javascript function to keep the button under your mouse while you’re hovering inside the input’s parent container. With the hardest part figured out, I had two additional goals:
- First, I needed it to display the file name of the uploaded file. One problem with Shaun’s is that I couldn’t even verify if I’d successfully attached a file.
- Second, I agree with Peter on the importance of being able to clear the file from the form. No implementation I’ve seen allows you to do that, so I added the feature.
To see how it’s done, you can either read the walkthrough or else download a working example.


