19

hi i was just wondering how you can create you own custom file upload button, because the best i can do is

enter image description here

and what i want to achieve is

enter image description here

if there is anyway of doing this i would be very thankful, and please can i have answers that explain how to do it with code and not answers with links to websites that allow you to download a button or something like that,Thank You :)

Praveen Gowda I V
  • 9,569
  • 4
  • 41
  • 49
olfek
  • 3,210
  • 4
  • 33
  • 49
  • It's a very big topic to explain how to do this :) – Karolis Jun 23 '11 at 22:20
  • @Karolis, there is a neat css trick that takes little explaination. See my answer below. – natedavisolds Jun 23 '11 at 22:49
  • @natedavisolds The author asked for explanation of how to do this. You gave a working example. I may be wrong but according to the question it seems that the author has very little knowledge about how HTML/CSS/JavasScript works. So that's why I think it's a very big topic to explain how to do this :) – Karolis Jun 24 '11 at 08:19
  • I used an image in the label tag. This did not work in IE8 out of the box, but then I captured the click event on the image using jQuery and triggered a click even to the input element. – rethab Sep 20 '13 at 09:24

8 Answers8

35

Although some of these answers will create something that looks like you want it to work, they will break down when they try to perform the way that you expect. The file input doesn't style well directly and you will have trouble trying it. However, there is a trick.

The trick is to turn the opacity of the input to 0 and then change the background underneath it to the button style that you want.

.file_button_container,
.file_button_container input {
     height: 47px;
     width: 263px;
 }

 .file_button_container {
     background: transparent url(https://i.stack.imgur.com/BT5AB.png) left top no-repeat;
 }

 .file_button_container input {
     opacity: 0;
 }
<div class="file_button_container"><input type="file" /></div>
Anup Yadav
  • 2,825
  • 3
  • 21
  • 30
natedavisolds
  • 4,305
  • 1
  • 20
  • 25
  • 2
    great solution. i'd like to add support in IE7 and IE8 can be done by including "-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0);" – Julian Apr 17 '12 at 20:39
  • @streetlight this worked for me in the latest Chrome for Mac, but I had to click run at the top – natedavisolds Oct 16 '12 at 15:56
  • @LeoHernandez there is a problem with the image uri... which I don't control. Sometimes it can pull the image and sometime it can't. It isn't a problem with the code though. – natedavisolds Mar 18 '13 at 15:31
  • @natedavisolds Hi, I found this when I realized my javascript button didn't work on IE 8 and FF. This works great, but it doesn't display the file name after I choose it. Is there a way to display that so the user knows that he has picked a file. +1 for the browser support though. – vinylDeveloper May 24 '13 at 04:34
  • I can I get the file name to display or a temp image thumb? – Papa De Beau Mar 05 '16 at 19:46
  • Thanks for sharing the simplest solution possible! – MHBN Jun 30 '20 at 18:37
24

I think you can also try doing it this way:
Creating an additional <label for="X"></label> element which you can style easily with CSS

<div class="container">
  <label for="upload" class="uploadButton">Upload</label>
  <input type="file" name="upload" id="upload">
</div>

like

.container {
  position: relative;
}
.uploadButton {
  height: 25px;
  width: 66px;
  display: block;
  cursor: pointer;
  background: url('http://www.ifunia.com/images/christmas/youtube-upload-button.gif') center center no-repeat;
}
input[type="file"] {
  display: block;
  width: 66px;
  height: 25px;
  clip: rect(0px 0px 0px 0px);
  position: absolute;
  left: 0;
  top: 0;
}
<form>
  <div class="container">
    <label for="upload" class="uploadButton"></label>
    <input type="file" name="upload" id="upload" required />
  </div>
  <hr/>
  <button type="submit">Submit</button>
</form>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 4
    you should get an award for this answer :) – Marius Ilie Oct 03 '13 at 13:06
  • I really prefer your solution because it's better on accessibility and customization. Nice idea ! – user1713964 Dec 20 '13 at 11:02
  • 1
    O wow! So simple, and so beautiful. How come this hasn't been found any sooner? The good thing is, you [can add two `label`s](http://stackoverflow.com/questions/17507738/does-label-for-attribute-has-to-be-unique), one for the actual labelling, and one for drawing a button – user123444555621 Dec 20 '13 at 13:21
  • 4
    There is one downside with using `display: none;`: it will also hide the browser's native validation tooltip. So you better use `opacity: 0; z-index: -1;` and position it right behind the label. See http://jsfiddle.net/MyYHx/ – user123444555621 Dec 22 '13 at 15:07
  • 1
    this is the best solution, but it should use `visibility: hidden` or `opacity: 0` (not `display:none`) – taseenb Jan 23 '14 at 09:34
  • I did `style="opacity:0; width:0px"`. – Namek Oct 10 '14 at 10:24
1

The arrow isn't something you can "just do with code" and the rounded corners would work fine in firefox, but not in ie using css... if you just need to use a custom image it's easy:

css:

#my_upload_button{
  background-image:url(path-to-file.png);
  border:none;
}
Trey
  • 5,480
  • 4
  • 23
  • 30
1

In Vue JS If you wanna put the upload image button inside the textarea use Relative and Absolute position to put the camera icon inside the textarea use bottom-3 right-4 to find the proper position

<div class="field relative">
        <label>Description</label>
        <textarea class="textarea" v-model="description" type="text" maxlength="10000"> </textarea>
        <label for="upload-file" class="icn icn-camera cursor-pointer absolute bottom-3 right-4">
          <input type="file" id="upload-file" hidden ref="file" @change="getImage($event)" accept="image/**" />
        </label>
  </div>

if not inside the textarea box, just one custom upload button then just keep the code like this

 <label for="upload-file" class="icn icn-camera cursor-pointer">
      <input type="file" id="upload-file" hidden ref="file" @change="getImage($event)" accept="image/**" />
    </label>

change the default upload file icon to a camera icon

Daisy
  • 288
  • 3
  • 8
0

Step 1. Create a simple html markup

<div class="fileUpload btn btn-primary">
    <span>Upload</span>
    <input type="file" class="upload" />
</div>

Step 2. CSS: Tricky Part

.fileUpload {
    position: relative;
    overflow: hidden;
    margin: 10px;
}
.fileUpload input.upload {
    position: absolute;
    top: 0;
    right: 0;
    margin: 0;
    padding: 0;
    font-size: 20px;
    cursor: pointer;
    opacity: 0;
    filter: alpha(opacity=0);
}

For demo see here http://geniuscarrier.com/how-to-style-a-html-file-upload-button-in-pure-css/

Alex
  • 1,033
  • 4
  • 23
  • 43
0

Use the input's label as custom upload button:

<label for="pic" class="uploadfilelabel" >upload </label>
<input type="hidden" name="MAX_FILE_SIZE" value="110000">
<input id="pic" name="pic" type="file" size="110000">

and CSS:

 label.uploadfilelabel{/*custom label here*/}
 input[type=file]{display:none;}

Notice that we did not display the main input button, because otherwise it will occupy space

Ormoz
  • 2,975
  • 10
  • 35
  • 50
0

I'm too late to answer but someone surely will find this useful in future, no need to use of Javascript or Hidden field too. If you are using Bootstrap then definitely there's no need of btn CSS as well.

#upload_file 
{
    display: none;
}

.btn-primary {
    background-color: #007bff;
    border-color: #007bff;
    color: #fff;
}

.btn {
    -moz-user-select: none;
    border: 1px solid transparent;
    border-radius: 0.25rem;
    display: inline-block;
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.5;
    padding: 0.375rem 0.75rem;
    text-align: center;
    transition: color 0.15s ease-in-out 0s, background-color 0.15s ease-in-out 0s, border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s;
    vertical-align: middle;
    white-space: nowrap;
}
<label for="upload_file" class="custom-file-upload btn btn-primary"><i class="fa fa-cloud-upload"></i> File Upload</label>
<input class="margin" type="file" formnovalidate id="upload_file" name="file" accept="*">
Anup Yadav
  • 2,825
  • 3
  • 21
  • 30
-1

Here is an approximation to the button you want with css/html

html

<button class="upload">Choose a file to upload...</button>

css

.upload{
    border:0;
    padding:10px 20px;
    -moz-border-radius:10px;
    border-radius:10px;
    background-color:#4488ee;
    color:white;
    font-size:16px;
}

demo http://jsfiddle.net/gaby/qdX5d/2/

for rounded corners in pre-IE9 use css3pie

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317