190

Is there a way to style (or script) <input type=file /> element to have visible only "Browse" button without text field?

Thanks

Edit: Just to clarify why to I need this. I'm using multi file upload code from http://www.morningz.com/?p=5 and it doesn't need input text field because it never has value. Script just adds newly selected file to collection on page. It would look much better without text field, if it's possible.

Alex Peters
  • 2,601
  • 1
  • 22
  • 29
Andrija
  • 14,037
  • 18
  • 60
  • 87

33 Answers33

232
<input type="file" id="selectedFile" style="display: none;" />
<input type="button" value="Browse..." onclick="document.getElementById('selectedFile').click();" />

This will surely work as I have used it in my projects.

Halo
  • 1,730
  • 1
  • 8
  • 31
shiba
  • 2,859
  • 1
  • 15
  • 9
  • 2
    This answer is so simple and elegant and has worked for all browsers. – Mike.C.Ford Mar 19 '15 at 15:55
  • This is by far the best solution I have found. It eliminates some real quirky file input style behavior with different mobile browsers. Now my file input control does not stand out like a sore thumb with the rest of my layout. Thanks much, wish I could up vote more than 1. – Highdown Aug 16 '16 at 15:21
  • ... and add onchange="this.form.submit();" to Input File element to start uploading after file selection. Do not forget to wrap all elements with Form tag. – Tomas Sep 12 '16 at 07:46
  • 1
    This won't work in IE8 and below as when submitting the form you will get an Access Denied error (you can't trigger file inputs with js in IE8 and below for "security reasons") – unenthusiasticuser Oct 03 '16 at 09:03
  • 3
    @unenthusiasticuser correct and won't work in ipad for same security reason . :) – Mahi Dec 29 '16 at 08:40
  • If you have jQuery `$(this).prev()[0].click()` will get you the previous file input without any knowledge of id. you can replace jQuery's `$(this).prev()[0]` with https://stackoverflow.com/questions/574904/get-next-previous-element-using-javascript#574922 for vanilla js: make a function `prev(el){ var nextSibling = el.nextSibling; while(nextSibling && nextSibling.nodeType != 1) { nextSibling = nextSibling.nextSibling } return nextSibling; }` Then it's just `` to get previous file input. optionally filter in the loop to skip elements – That Realty Programmer Guy Apr 19 '18 at 03:41
  • additionally if you style opacity to 0, width and height to 0.1px, position to absolute and z-index to a negative; you will not run into issues with the file input not submitting and the element will not be in your way – That Realty Programmer Guy Apr 19 '18 at 03:43
  • Another caveat is that `Browse...` is hard-coded English, whereas the browser might localise the text for a file input button. – c24w Jan 29 '19 at 17:15
  • @c24w I can't really think of a case where the button and page would be in two different languages and the user only understood one of them. Any opportunity to translate the page would also be an opportunity to translate the button. – Jason C Apr 03 '22 at 21:58
83

I was having a heck of a time trying to accomplish this. I didn't want to use a Flash solution, and none of the jQuery libraries I looked at were reliable across all browsers.

I came up with my own solution, which is implemented completely in CSS (except for the onclick style change to make the button appear 'clicked').

You can try a working example here: http://jsfiddle.net/VQJ9V/307/ (Tested in FF 7, IE 9, Safari 5, Opera 11 and Chrome 14)

It works by creating a big file input (with font-size:50px), then wrapping it in a div that has a fixed size and overflow:hidden. The input is then only visible through this "window" div. The div can be given a background image or color, text can be added, and the input can be made transparent to reveal the div background:

HTML:

<div class="inputWrapper">
    <input class="fileInput" type="file" name="file1"/>
</div>

CSS:

.inputWrapper {
    height: 32px;
    width: 64px;
    overflow: hidden;
    position: relative;
    cursor: pointer;
    /*Using a background color, but you can use a background image to represent a button*/
    background-color: #DDF;
}
.fileInput {
    cursor: pointer;
    height: 100%;
    position:absolute;
    top: 0;
    right: 0;
    z-index: 99;
    /*This makes the button huge. If you want a bigger button, increase the font size*/
    font-size:50px;
    /*Opacity settings for all browsers*/
    opacity: 0;
    -moz-opacity: 0;
    filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0)
}

Let me know if there are any problems with it and I'll try to fix them.

ampersandre
  • 3,156
  • 3
  • 29
  • 37
  • 4
    this was the best solution that I came across that worked with all browsers – Fatal Aug 24 '12 at 05:06
  • 2
    You're the man. I've been struggling with this issue on FF and your solution is the only one that truly works, specially with bigger buttons by increasing its active area using "font-size". Thanks! :) – jpincheira Jan 24 '13 at 16:19
  • 2
    Excellent one without using any script – Bujji Jun 05 '13 at 21:45
  • 1
    Twitter does it but it was a bit convoluted compared to this one. Working well for me! – volume one Jul 11 '14 at 23:17
  • good solution! Just one question: why don't you give .fileInput a width of 100% and set .inputWrapper's width to auto? – luin Jan 28 '15 at 16:14
  • @Luin, at the time that I wrote this, setting the width on a `` element was not supported by Firefox. Instead, setting the font-size to 50px (or some other large number) was a cross-browser safe way of making sure the file input element was very large. The `.inputWrapper` serves as a "window" from which the file input can be seen and clicked on; the width of the .inputWrapper defines the width of your button. For my requirements, I needed to make sure the button was 64px wide, so I set the .inputWrapper width to 64px. – ampersandre Jan 28 '15 at 16:20
  • @ampersandre I set inputWrapper `display: inline-block`, and then it can auto-resizing according to its content: http://jsfiddle.net/4prm4pxu/3/ – luin Jan 28 '15 at 16:37
  • You can avoid the use of `opacity` in `.fileInput` by setting its `left:200px`, which scrolls the 'Browse...' button out of visible sight within the outer div. But you also must then set an `onclick` on the div to call `fileInput.click()`. – David R Tribble Feb 23 '16 at 22:56
  • ...or you might try setting the `padding-left` to a value at least as wide as the outer button div, to hide the button itself. – David R Tribble Apr 08 '16 at 22:52
52

I wasted my day today getting this to work. I found none of the solutions here working each of my scenarios.

Then I remembered I saw an example for the JQuery File Upload without text box. So what I did is that I took their example and stripped it down to the relevant part.

This solution at least works for IE and FF and can be fully styled. In the below example the file input is hidden under the fancy "Add Files" button.

<html>

<head>
    <title>jQuery File Upload Example</title>
    <style type="text/css">
        .myfileupload-buttonbar input
        {
            position: absolute;
            top: 0;
            right: 0;
            margin: 0;
            border: solid transparent;
            border-width: 0 0 100px 200px;
            opacity: 0.0;
            filter: alpha(opacity=0);
            -o-transform: translate(250px, -50px) scale(1);
            -moz-transform: translate(-300px, 0) scale(4);
            direction: ltr;
            cursor: pointer;
        }
        .myui-button
        {
            position: relative;
            cursor: pointer;
            text-align: center;
            overflow: visible;
            background-color: red;
            overflow: hidden;
        }
    </style>
</head>
<body>
    <div id="fileupload" >
        <div class="myfileupload-buttonbar ">
            <label class="myui-button">
                <span >Add Files</span>
                <input id="file" type="file" name="files[]" />
            </label>
        </div>
    </div>
</body>
</html>
PHPGuru
  • 398
  • 3
  • 9
tmanthey
  • 4,547
  • 6
  • 35
  • 42
28

Add a label tag with for attribute assign the for attribute value to the file input button.
Now when you click the label, the browser will open up the file browse dialogue popup automatically.
Note: Hide the file input button using CSS.

Check the live demo below.

$('#imageUpload').change(function() {
  readImgUrlAndPreview(this);

  function readImgUrlAndPreview(input) {
    if (input.files && input.files[0]) {
      var reader = new FileReader();
      reader.onload = function(e) {
        $('#imagePreview').removeClass('hide').attr('src', e.target.result);
      }
    };
    reader.readAsDataURL(input.files[0]);
  }
});
.hide {
  display: none;
}

.btn {
  display: inline-block;
  padding: 4px 12px;
  margin-bottom: 0;
  font-size: 14px;
  line-height: 20px;
  color: #333333;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
  border: 1px solid #ddd;
  box-shadow: 2px 2px 10px #eee;
  border-radius: 4px;
}

.btn-large {
  padding: 11px 19px;
  font-size: 17.5px;
  -webkit-border-radius: 4px;
  -moz-border-radius: 4px;
  border-radius: 4px;
}

#imagePreview {
  margin: 15px 0 0 0;
  border: 2px solid #ddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<div clas="file_input_wrap">
  <input type="file" name="imageUpload" id="imageUpload" class="hide" />
  <label for="imageUpload" class="btn btn-large">Select file</label>
</div>
<div class="img_preview_wrap">
  <img src="" id="imagePreview" alt="Preview Image" width="200px" class="hide" />
</div>
Suresh Pattu
  • 6,083
  • 16
  • 59
  • 91
26

I tried to implement the top two solutions, and it ended up being a HUGE waste of time for me. In the end, applying this .css class solved the problem...

input[type='file'] {
  color: transparent;
}

Done! super clean and super simple...

nikotromus
  • 1,015
  • 16
  • 36
25

Hide the input-file element and create a visible button that will trigger the click event of that input-file.

Try this:

CSS

#file { width:0; height:0; } 

HTML:

<input type='file' id='file' name='file' />
<button id='btn-upload'>Upload</button>

JAVASCRIPT(jQuery):

$(function(){
    $('#btn-upload').click(function(e){
        e.preventDefault();
        $('#file').click();}
    );
});
DavidO
  • 13,812
  • 3
  • 38
  • 66
jojo
  • 259
  • 3
  • 2
  • I've made a jQuery plugin that does all that work for you: https://github.com/mbitto/jquery.buttonFile – Manuel Bitto Jan 26 '13 at 01:28
  • This doesn't work in the newer versions of IE. The indirect click causes IE to flip out and deny access. It's annoying. – Andrew Mar 12 '14 at 17:32
17

That's going to be very hard. The problem with the file input type is that it usually consists of two visual elements, while being treated as a single DOM-element. Add to that that several browsers have their own distinct look and feel for the file input, and you're set for nightmare. See this article on quirksmode.org about the quirks the file input has. I guarantee you it won't make you happy (I speak from experience).

[EDIT]

Actually, I think you might get away with putting your input in a container element (like a div), and adding a negative margin to the element. Effectively hiding the textbox part off screen. Another option would be to use the technique in the article I linked, to try to style it like a button.

Erik van Brakel
  • 23,220
  • 2
  • 52
  • 66
  • 4
    That article on quirksmode is great. Styling file inputs are still a pain though. :P – MitMaro Jul 05 '09 at 22:12
  • I don't think the contained netagive-margin will work well once you take into account different browser styles and minimum font sizes being different from user to user. – joebert Jul 06 '09 at 08:58
  • 1
    joebert: I agree, I think the best option is still the technique displayed in the quirksmode article, how painfully hackish... – Erik van Brakel Jul 06 '09 at 09:22
14

Fix to work in all browsers RESOLVED:

      <input type = "button" value = "Choose image" 
       onclick ="javascript:document.getElementById('imagefile').click();">
      <input id = "imagefile" type="file" style='visibility: hidden;' name="img"/>

I have tested in FF, Chrome & IE - working fine, applied styles too :D

Community
  • 1
  • 1
Javier Reyes
  • 181
  • 1
  • 2
  • 6
    I'm pretty sure that doesn't work on a whole number of browsers (including FF and IE, when I last tested) - the only browser I remember it working on was Chrome. – Herman Schaaf May 04 '11 at 22:47
  • That only works with jQuery, but it's not a standalone solution. – Solenoid Sep 24 '11 at 22:51
  • 3
    This *appears* to work (it brings up the file chooser menu), but when the form is submitted, the file is not sent in FireFox and IE, for security reasons. – ampersandre Oct 07 '11 at 17:24
10

Another easy way of doing this. Make a "input type file" tag in html and hide it. Then click a button and format it according to need. After this use javascript/jquery to programmatically click the input tag when the button is clicked.

HTML :-

<input id="file" type="file" style="display: none;">
<button id="button">Add file</button>

JavaScript :-

document.getElementById('button').addEventListener("click", function() {
    document.getElementById('file').click();
});

jQuery :-

$('#button').click(function(){
    $('#file').click();
});

CSS :-

#button
{
    background-color: blue;
    color: white;
}

Here is a working JS fiddle for the same :- http://jsfiddle.net/32na3/

divyenduz
  • 2,037
  • 19
  • 38
  • 2
    This is a neat solution but I can't get it to work in Chrome. Apparently others can't either. Opera and Chrome don't allow click on input type file for security reasons. Here you can find more about this and a solution that worked for me: http://stackoverflow.com/a/3030174/2650732 – wojjas Aug 24 '15 at 14:14
  • Back when I wrote this answer, it worked on chrome. Thanks for letting me know, will update my answer accordingly – divyenduz Aug 24 '15 at 17:45
10

Here is my good ol' remedy:

<input type="file" id="myFile" style="display:none;" />
<button type="button" onclick="document.getElementById('myFile').click();">Browse</button>

At least it worked in Safari.

Plain and simple.

Zooza S
  • 307
  • 1
  • 4
  • 17
6

I used some of the code recommended above and after many hours of waisting my time, I eventually came to a css bag free solution.

You can run it over here - http://jsfiddle.net/WqGph/

but then found a better solution - http://jsfiddle.net/XMMc4/5/

 <input type = "button" value = "Choose image #2" 
   onclick ="javascript:document.getElementById('imagefile').click();">
       <input id = "imagefile" type="file" style='display:none;' name="img" value="none"/>see jsfiddle code for examples<br/>
GoreOle
  • 61
  • 1
  • 3
4

You could label an image so when you click on it the click event of the button will be triggered. You can simply make the normal button invisible:

<form>
    <label for="fileButton"><img src="YourSource"></label>    <!--You don't have to put an image here, it can be anything you like-->
    <input type="file" id="fileButton" style="display:none;"/>
</form>

It worked for me on all browsers, and is very easy to use.

D-Inventor
  • 41
  • 1
4

You can dispatch the click event on a hidden file input like this:

<form action="#type your action here" method="POST" enctype="multipart/form-data">
     <div id="yourBtn" style="height: 50px; width: 100px;border: 1px dashed #BBB; cursor:pointer;" >Click to upload!</div>
     <!-- hide input[type=file]!-->
     <div style='height: 0px;width:0px; overflow:hidden;'><input id="upfile" type="file" value="upload"/></div>
     <input type="submit" value='submit' >
    </form>

    <script type="text/javascript">
     var btn = document.getElementById("yourBtn");
     var upfile = document.getElementById("upfile"); 
     btn.addEventListener('click',function(){
      if(document.createEvent){
       var ev = document.createEvent('MouseEvents');
       ev.initEvent('click',true,false);
       upfile.dispatchEvent(ev);
      }else{
          upfile.click();
      }
     });
    
    </script>
Fabian Schmengler
  • 24,155
  • 9
  • 79
  • 111
jiang min
  • 49
  • 2
4

HTML:

<input type="file" name="upload" id="upload" style="display:none"></input>
    <button  id="browse">Upload</button>

JQUERY

 $(document).ready(function(){
        $("#browse").click(function(){
        $("#upload").click();
        });
 });

Hope this works :)

Anoop saju
  • 480
  • 3
  • 17
4

This HTML code show up only Upload File button

<form action="/action_page.php">
    <input type="button" id="id" value="Upload File"  onclick="document.getElementById('file').click();" />
    <input type="file" style="display:none;" id="file" name="file" onchange="this.form.submit()"/>  
</form>
stelioslogothetis
  • 9,371
  • 3
  • 28
  • 53
  • 1
    Please consider adding some contextual information to your answer which describes what your code snippet does. – Clijsters Sep 01 '17 at 09:44
4

You can give the input element a font opacity of 0. This will hide the text field without hiding the 'Choose Files' button.

No javascript required, clear cross browser as far back as IE 9

E.g.,

input {color: rgba(0, 0, 0, 0);}
nicholmen
  • 41
  • 2
3

Ive a really hacky solution with this...

<style type="text/css"> 
    input[type="file"]
    { 
        width: 80px;        
    } 
</style>

<input id="File1" type="file" />

The problem is the width attribute that is hiding the text field will obvously vary between browsers, vary between Windows XP themes and so on. Maybe its something you can work with though?...

3

I know this is an old post but a simple way to make the text dissapear is just to set text color to that of your background.

eg if your text input background is white then:

input[type="file"]{
color:#fff;
}

This will not effect the Choose File text which will still be black due to the browser.

Keleko
  • 245
  • 4
  • 15
3

There is a simple and hacky way to show only the file input button while keeping the render and translations of this file input button :

Make the text that is displayed after a file input invisible using a the color transparent.

<input type="file" style="color: transparent" />
Maxime Ancelin
  • 870
  • 9
  • 11
2

This works for me:

input[type="file"]  {
    color: white!important;
}
StarsSky
  • 6,721
  • 6
  • 38
  • 63
newbie
  • 14,582
  • 31
  • 104
  • 146
2

I just styled an input file with width: 85px, and the text field disappeared at all

  • So did the text field disappear or not? "at all" mighr imply a negation there, but your grammar is flawed (and thus ambiguous). – Kirk Woll Apr 21 '14 at 00:55
2

my solution is just to set it within a div like "druveen" said, however i ad my own button style to the div (make it look like a button with a:hover) and i just set the style "opacity:0;" to the input. Works a charm for me, hope it does the same for you.

ThomasG
  • 21
  • 1
1
<a href="#" id="select_logo">Select Logo</a> <input type="file" id="logo"> 

$("#logo").css('opacity','0');

$("#select_logo").click(function(){
   $().trigger('click');
   return false;
});
Somwang Souksavatd
  • 4,947
  • 32
  • 30
1

For me, the simplest way is using a font color like background color. Simple, not elegant, but usefull.

<div style="color:#FFFFFF">   <!-- if background page is white, of course -->
<input class="fileInput" type="file" name="file1"/></div>
1

So here's the best way to do this FOR ALL BROWSERS:

Forget CSS!

<p>Append Image:</p> 
<input type="button" id="clickImage" value="Add Image" />
<input type="file" name="images[]" id="images" multiple />

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" charset="utf-8"></script>

<script>
$('#images').hide();        
$('#clickImage').click( function() {    
    $('#images').trigger('click');  
});
</script>
  • THIS WON'T WORK IN SAFARI... since it won't allow .trigger('click') for security reasons :? to make it work in safari dynamically create the file button and re-add it when it's loaded again – user1965301 Feb 27 '13 at 04:00
1

All these answers are cute, but CSS won't work since it isn't the same across all browsers and devices, the first answer I wrote will work in everything but Safari. To get it to work accross all browsers all the time it must be created dynamically and recreated every time you want to clear the input text:

    var imageDiv = document.createElement("div");   
    imageDiv.setAttribute("id", "imagediv");
    imageDiv.style.cssText = 'position:relative; vertical-align: bottom;';  
    var imageText = document.createTextNode("Append Image:");
    var newLine = document.createElement("br"); 
    var image = document.createElement("input");    
    image.setAttribute("type", "file");
    image.setAttribute("id", "images");
    image.setAttribute("name", "images[]");     
    image.setAttribute("multiple", "multiple");
    imageDiv.appendChild(imageText); 
    imageDiv.appendChild(newLine); 
    imageDiv.appendChild(image); 
    questionParagraph.appendChild(imageDiv);
1

The answer of tmanthey is quite good, except that you can't play with border-width in Firefox v20. If you see the link (demo, can't really show here) they solved the problem using font-size=23px, transform:translate(-300px, 0px) scale(4) for Firefox to get the button bigger.

Other solutions using .click() on a different div is useless if you want to make it a drag'n'drop input box.

Tim Post
  • 33,371
  • 15
  • 110
  • 174
1

There are several valid options here but thought I would give what I have come up with while trying to fix a similar issue. http://jsfiddle.net/5RyrG/1/

<span class="btn fileinput-button">
    <span>Import Field(s)</span>
    <input id="fileupload" type="file" name="files[]" onchange="handleFiles(this.files)" multiple>
</span>
<div id="txt"></div>

function handleFiles(files){
    $('#txt').text(files[0].name);  
}
Matthew Pautzke
  • 548
  • 5
  • 13
1

I wrote this:

<form action='' method='POST' name='form-upload-image' id='form-upload-image' enctype='multipart/form-data'>

    <div style="width: 0; height: 0; overflow: hidden;">
        <input type="file" name="input-file" id="input-file" onchange="this.files.length > 0 ? document.getElementById('form-upload-image').submit():null;" />
    </div>
    
</form>

<img src="image.jpg" style="cursor: pointer;" onclick="document.getElementById('input-file').click();" />

Work fine in all browsers, no jQuery, no CSS.

MadMaxIII
  • 11
  • 1
1

Here is a simplified version of @ampersandre's popular solution that works in all major browsers. Asp.NET markup

<asp:TextBox runat="server" ID="FilePath" CssClass="form-control"
    style="float:left; display:inline; margin-right:5px; width:300px"
    ReadOnly="True" ClientIDMode="Static" />
<div class="inputWrapper">
    <div id="UploadFile" style="height:38px; font-size:16px; 
      text-align:center">Upload File</div>
    <div>
      <input name="FileUpload" id="FileInput" runat="server" 
             type="File" />
    </div>
  </div>
  <asp:Button ID="UploadButton" runat="server" 
    style="display:none" OnClick="UploadButton_Click" />
</div>
<asp:HiddenField ID="hdnFileName" runat="server" ClientIDMode="Static" />

JQuery Code

$(document).ready(function () {

   $('#UploadFile').click(function () {
       alert('UploadFile clicked');
       $('[id$="FileInput"]').trigger('click');
   });

   $('[id$="FileInput"]').change(function (event) {
       var target = event.target;
       var tmpFile = target.files[0].name;
       alert('FileInput changed:' + tmpFile);
       if (tmpFile.length > 0) {
          $('#hdnFileName').val(tmpFile);
       }
       $('[id$="UploadButton"]').trigger('click');
   });
});

css code

.inputWrapper {
height: 38px;
width: 102px;
overflow: hidden;
position: relative;
padding: 6px 6px;
cursor: pointer;
white-space:nowrap;
/*Using a background color, but you can use a background image to represent
 a button*/
background-color: #DEDEDE;
border: 1px solid gray;
border-radius: 4px;
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
user-select: none;
}

Uses a hidden "UploadButton" click trigger for server postback with standard . The with "Upload File" text pushes the input control out of view in the wrapper div when it overflows so there is no need to apply any styles for the "file input" control div. The $([id$="FileInput"]) selector allows section of ids with standard ASP.NET prefixes applied. The FilePath textbox value in set from server code behind from hdnFileName.Value once file is uploaded.

Dan Randolph
  • 741
  • 8
  • 14
1

I Don't Know what your talking about, if you trying to style a input type file into a button that is easy for me all you will need is just html and CSS.

#File-Body>#File-For {
  display: none;
}

#Filebutton {
  width: 50px;
  height: 20px;
  border: 1px solid;
  border-radius: 2px;
  text-align: center;
}

#File-Body {
  width: 300px;
  height: 30px;
}
<div id="File-Body">
  <label id="File-Lable" for="File-For">
    <div id="Filebutton">Edit</div>
  </label>
  <input id="File-For" type="file">
</div>

If you want to test it Here it is http://jsfiddle.net/qm8j45c3/

isherwood
  • 58,414
  • 16
  • 114
  • 157
Gamer Vang
  • 32
  • 1
  • 10
0

Resolved with the following code:

<div style="overflow: hidden;width:83px;"> <input style='float:right;' name="userfile" id="userfile" type="file"/> </div>

StarsSky
  • 6,721
  • 6
  • 38
  • 63
druveen
  • 1,611
  • 3
  • 15
  • 32
0

In React

const hiddenBrowseButton = React.useRef(null)

<input ref={hiddenBrowseButton} type="file" style={{"display": "none"}} /> # hides original button
<button onClick={() => hiddenBrowseButton.current.click()}>Your Text</button> # visible button

When the visible button is clicked, it automatically clicks the hidden button.

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 10 '23 at 13:48