Go back to the main page

Better way to do file uploads in HTML



Webkit based browsers have a nice way to render the <input type="file" /> HTML tag in that it doesn't the full directory of the file you are uploading — only the file name itself. Displaying the entire directory path is an annoyance as it doesn't give you immediate feedback that you've selected the correct file name. So you have to grab the mouse and select inside the field and scroll all the way over to the right.

Fig. 1 Webkit rendering of <input type="file" /> Nice as it only shows the file name and not the directory

Webkit rendering of file upload HTML tag

Fig. 2 Non-Webkit rendering of <input type="file" /> Bad as it shows the directory

Non-Webkit rendering of file upload HTML tag


There have been a decent number of solutions for making the input[type=file] nicer. I liked Shaun Inman's approach best; however, it was more about button styling and I wanted that plus filename only,remove, and add another link. Hence the FileCabinet class ( Prototype.js based ).

Fig. 3 FileCabinet rendering of <input type="file" /> Better, much better

Filecabinet rendering of file upload HTML tag

HTML and CSS prerequisites.

Required HTML. You need to have a bit of HTML that defines the "add an attachment" action. For example.

<span id="addAttachment"></span>

Required CSS.

      input.uploadFields {
        opacity: 0;
        position: relative;
        -moz-opacity: 0;

        width: 79px;
        height: 22px;
        background: url(btn-choose-file.gif) 0 0 no-repeat;
        display: block;
        overflow: hidden;
        cursor: pointer;


      document.observe( 'dom:loaded',function(){
        new FileCabinet('addAttachment');


There are two options:


new FileCabinet('addAttachment',{ tableWidth: 40 });
Default is 100% e.g. Defines in percentage the width of the table row each new row.


new FileCabinet('addAttachment',{ newElClassName: 'fileCabRow' });
Default is "row" e.g. Defines the class name for each new row. You may want something more descriptive if the class name of "row" is too generic and conflicts with other CSS rules.

Final Notes:

  • Demo is here.
  • Code is here.
  • Tested in IE 6+,Firefox 3,Chrome 4,Safari 4
  • Pushed on 04/08/2010 by Christian