The trick to styling a file input is that you
A) give the style you want to the input’s
inputitself (except for hiding it)
and B) explicitly cause the
labelto delegate a
(rather than the default focus-on-click).
TL;DR (Short ’n’ Sweet)
Hide the original file input by absolutely positioning it off screen:
<input type="file" style="position: absolute; top: -10000px; left: -10000px" />
Style the surrounding
labelhowever you like:
<label style=" border: 1px solid red; background-color: lightgray; padding: 1em; cursor: pointer; user-select: none; " >Upload File <input ... /></label>
labelto delegate to the
<label style="..." onclick=" document.body .querySelector('[name=js-file-upload]') .dispatchEvent( new MouseEvent('click') ); " >Upload File <input ... /></label>
How does it work?
input will receive focus when you click on its
label - as if you had clicked on the input itself.
<input type="file" />, however, is a special case. Rather than just focusing the cursor on the input, you actually want a file open dialog to appear. This requires delegation of the click, not just the focus.
Complete Code Example
In this example I’m letting the
click event bubble to the
form and then I catch and delegate it to the
<h1>Styled File-Input Demo</h1> <form action="" onclick=" document.body.querySelector('[name=js-file-upload]').dispatchEvent( new MouseEvent('click') ); " > <label for="js-file-upload" style=" border: 1px solid red; padding: 1em; cursor: pointer; user-select: none; " >Upload File <input style="position: absolute; top: -10000px; left: -10000px" name="js-file-upload" type="file" multiple /> </label> </form>
You may encounter a lot of much fancier ways to do this, with much fancier explanations.
Those are, generally speaking, bad ideas.
label is the semantically correct thing to do - it’s how HTML was designed since the beginning.
It’s boring because it works (and has worked since the 90s), which is great!
This doesn’t require any special frameworks or plugins, and will work better both in browser support and for accessibility than doing the more complex things that go against the standard browser behavior.