The best way is to make the file input control almost invisible (by giving it a very low opacity - do not do "visibility: hidden" or "display: none") and absolutely position something under it - with a lower z-index.
This way, the actual control will not be visible, and whatever you put under it will show through. But since the control is positioned above that button, it will still capture the click events (this is why you want to use opacity, not visibility or display - browsers make the element unclickable if you use those to hide it).
This article goes in-depth on the technique.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…