Many of the answers above are quite old. In 2013 a much simpler solution exists: nearly all current browsers…
- Chrome
- IE
- Safari
- Firefox with a few-line fix
pass through click events from labels. Try it here: http://jsfiddle.net/rvCBX/7/
- Style the
<label>
however you you would like your file upload to be. - Set
for="someid"
attribute on the label - Create a
<input id="someid">
element, that’s hidden.
Clicking the label will passthrough the event to the fileupload in Chrome, IE, and Safari.
Firefox requires a very small workaround, which is detailed in this answer.