Because of the heap of security issues associated with the operation of files, they are quite difficult to fix. However, what works is this scheme:
- Create your own look at entering a file that is reasonably close to the default size and default form.
- Place your input file and the actual file input in the same place on your form, with the real one above your
- Make the real input transparent (i.e. set the opacity to zero)
Now clicks on your elements that you want them to look will actually be interpreted by the browser as clicks on the input of the file. You have to configure something for IE a bit, because IE7 allows the user to enter data directly into the input, and other browsers immediately launch the file selection when the element is clicked anywhere.
edit - here is a jsfiddle that works, at least in Chrome. HTML:
<div class='fancy-file'> <div class='fancy-file-name'> </div> <button class='fancy-file-button'>Browse...</button> <div class='input-container'> <input type='file'> </div> </div>
This wraps a "fake" input file, which I will use with my own CSS, as well as with the actual <input> element. Here's the CSS:
div.fancy-file { position: relative; overflow: hidden; cursor: pointer; } div.fancy-file-name { float: left; border-radius: 3px; background-color: #aaa; box-shadow: inset 1px 1px 3px #eee, inset -1px -1px 3px #888, 1px 1px 3px #222; font-weight: bold; font-family: Courier New, fixed; width: 155px; font-size: 12px; padding: 1px 4px; } button.fancy-file-button { float: left; border-radius: 3px; border: 1px solid red; background-color: #F5BD07; font-weight: bold; vertical-align: top; margin: 0 0 0 3px; } div.input-container { position: absolute; top: 0; left: 0; } div.input-container input { opacity: 0; }
The outer container is made "position: relative" to simplify the position of the real <input> over the fake material. The fake stuff has my fancy stylish styles, and it has a size so that it is about the same as the total size of the actual file input. This is absolutely positioned and transparent.
Here are some jQuery to manage it:
$('div.fancy-file input:file').bind('change blur', function() { var $inp = $(this), fn; fn = $inp.val(); if (/fakepath/.test(fn)) fn = fn.replace(/^.*\\/, ''); $inp.closest('.fancy-file').find('.fancy-file-name').text(fn); });
Browsers will not give you the full path, but they will provide you with some of this. Some browsers (Chrome and IE) give you an explicitly fake path prefix, so the code removes it (because it is useless).