Twitter Bootstrap Form File Element Upload Button

Here's a solution for Bootstrap 3, 4, and 5.

To make a functional file input control that looks like a button, you only need HTML:

HTML

<label class="btn btn-default">
    Browse <input type="file" hidden>
</label>

This works in all modern browsers, including IE9+. If you need support for old IE as well, please use the legacy approach shown below.

This techniques relies on the HTML5 hidden attribute. Bootstrap 4 uses the following CSS to shim this feature in unsupportive browsers. You may need to add if you're using Bootstrap 3.

[hidden] {
  display: none !important;
}

Legacy approach for old IE

If you need support for IE8 and below, use the following HTML/CSS:

HTML

<span class="btn btn-default btn-file">
    Browse <input type="file">
</span>

CSS

.btn-file {
    position: relative;
    overflow: hidden;
}
.btn-file input[type=file] {
    position: absolute;
    top: 0;
    right: 0;
    min-width: 100%;
    min-height: 100%;
    font-size: 100px;
    text-align: right;
    filter: alpha(opacity=0);
    opacity: 0;
    outline: none;
    background: white;
    cursor: inherit;
    display: block;
}

Note that old IE doesn't trigger the file input when you click on a <label>, so the The CSS "bloat" does a couple things to work around that:

  • Makes the file input span the full width/height of the surrounding <span>
  • Makes the file input invisible

Feedback & Additional Reading

I've posted more details about this method, as well as examples for how to show the user which/how many files are selected:

https://www.abeautifulsite.net/posts/whipping-file-inputs-into-shape-with-bootstrap-3/


Im surprised there was no mention of the <label> element.

Solution:

<label class="btn btn-primary" for="my-file-selector">
    <input id="my-file-selector" type="file" class="d-none">
    Button Text Here
</label>

No need for any JS, or funky css...

Solution for including the filename:

<label class="btn btn-primary" for="my-file-selector">
    <input id="my-file-selector" type="file" style="display:none" 
    onchange="$('#upload-file-info').text(this.files[0].name)">
    Button Text Here
</label>
<span class='label label-info' id="upload-file-info"></span>

The solution above requires jQuery.

Note: use $.text() when displaying user-supplied content on the page. An earlier version of this answer used $.html() which is not safe – filenames can contain HTML markup.