Replace input type=file by an image
Like a lot of people, I'd like to customize the ugly input type=file
, and I know that it can't be done without some hacks and/or javascript
. But, the thing is that in my case the upload file buttons are just for uploading images (jpeg|jpg|png|gif), so I was wondering if I could use a "clickable
" image which would act exactly as an input type file (show the dialog box, and same $_FILE on submitted page).
I found some workaround here, and this interesting one too (but does not work on Chrome =/).
What do you guys do when you want to add some style to your file buttons? If you have any point of view about it, just hit the answer button ;)
This works really well for me:
.image-upload>input {
display: none;
}
<div class="image-upload">
<label for="file-input">
<img src="https://icons.iconarchive.com/icons/dtafalonso/android-lollipop/128/Downloads-icon.png"/>
</label>
<input id="file-input" type="file" />
</div>
Basically the for attribute of the label makes it so that clicking the label is the same as clicking the specified input.
Also, the display property set to none makes it so that the file input isn't rendered at all, hiding it nice and clean.
Tested in Chrome but according to the web should work on all major browsers. :)
EDIT: Added JSFiddle here: https://jsfiddle.net/c5s42vdz/
Actually it can be done in pure css and it's pretty easy...
HTML Code
<label class="filebutton">
Browse For File!
<span><input type="file" id="myfile" name="myfile"></span>
</label>
CSS Styles
label.filebutton {
width:120px;
height:40px;
overflow:hidden;
position:relative;
background-color:#ccc;
}
label span input {
z-index: 999;
line-height: 0;
font-size: 50px;
position: absolute;
top: -2px;
left: -700px;
opacity: 0;
filter: alpha(opacity = 0);
-ms-filter: "alpha(opacity=0)";
cursor: pointer;
_cursor: hand;
margin: 0;
padding:0;
}
The idea is to position the input absolutely inside your label. set the font size of the input to something large, which will increase the size of the "browse" button. It then takes some trial and error using the negative left / top properties to position the input browse button behind your label.
When positioning the button, set the alpha to 1. When you've finished set it back to 0 (so you can see what you're doing!)
Make sure you test across browsers because they'll all render the input button a slightly different size.
Great solution by @hardsetting, But I made some improvements to make it work with Safari(5.1.7) in windows
.image-upload > input {
visibility:hidden;
width:0;
height:0
}
<div class="image-upload">
<label for="file-input">
<img src="https://placehold.it/100/000000/ffffff?text=UPLOAD" style="pointer-events: none"/>
</label>
<input id="file-input" type="file" />
</div>
I have used visibility: hidden, width:0
instead of display: none
for safari issue and added pointer-events: none
in img
tag to make it working if input file type tag is in FORM tag.
Seems working for me in all major browsers.
Hope it helps someone.
A much better way than writing JS is to use native, and it turns to be lighter than what was suggested:
<label>
<img src="my-image.png">
<input type="file" name="myfile" style="display:none">
</label>
This way the label
is automatically connected to the input that is hidden.
Clicking on the label is like clicking on the field.