Last Updated: June 11, 2021
·
5.665K
· moak

Style file uploads via label

Well, the file upload input is one of the harder to style form elements, so I thought, let's just hide it and style a simple label tag instead.

First, grab a style you like from http://www.cssbuttongenerator.com/ or similar sites.

Here's the markup:

<form id="imageUploadForm" method="post" action="/image/upload" enctype="multipart/form-data">
    <label id="imageUploadLabel" for="imageUpload" class="button">Upload Picture</label>
    <input id="imageUpload" type="file" accept="image/*" capture="camera" name="file" style="display:none;">
</form>

and a small jQuery fix for Firefox

if($.browser.mozilla) {
  $(document).on('click', 'label', function(e) {
    if(e.currentTarget === this && e.target.nodeName !== 'INPUT') {
      $(this.control).click();
    }
  });
}

Now you might want to indicate that a file was selected when the input field changes:

var $input = $('#imageUpload'),
$label = $('#imageUploadLabel');
$input.change(function(){
    if($input.val().length > 0){
        $label.addClass('file-selected');
    }else{
        $label.removeClass('file-selected');
    }
});

And even better, upload the image once it's been selected using ajaxSubmit function from https://github.com/malsup/form/ and make the button animate using an image from http://ajaxload.info/

var $input = $('#imageUpload');
var $label = $('#imageUploadLabel');
$input.change(function(){
    if($input.val().length > 0){
        $label.addClass('uploading');
        $input.parent().ajaxSubmit({
            success:function(){
                $label.removeClass('uploading');
                //do something
            },
            clearData: true,
            error: function(e){
                $label.removeClass('uploading');
                //do something
            }
        });
    }
});

Tested on today's versions of Chrome, Firefox and IE9
Here's the code based on redeyes2015's jFiddle

http://jsfiddle.net/nGeBb/5/
As he noted for IE8 you might need to hide the element in a different way, maybe try 0 height and 0 width or similar, whatever works for you

2 Responses
Add your response

Awesome tip!
While "display: none" seems to break the trick on IE8, something like " position: fixed; left: 1000%;" may bring it back. A jsfiddle might explain better: http://jsfiddle.net/redeyes2015/Af3VJ/ . Thanks for great tip again.

over 1 year ago ·

Great tip! Very useful
Thanks!

over 1 year ago ·