Here is a good post on how to do it.
Following is quoted from above article:
- Take a normal < type="file">
- To this same parent element, add a normal <> and an image, which have the correct styles. Position these elements absolutely, so that they occupy the same place as the < type="file">.
- Set the z-index of the < type="file"> to 2 so that it lies on top of the styled input/image.
- Finally, set the opacity of the < type="file"> to 0. The < type="file"> now becomes effectively invisible, and the styles input/image shines through, but you can still click on the "Browse" button. If the button is positioned on top of the image, the user appears to click on the image and gets the normal file selection window.
(Note that you can't use visibility: hidden, because a truly invisible element is unclickable, too, and we need the < type="file"> to remain clickable)