Last Updated: June 11, 2021
·
6.013K
· 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 ·

Have a fresh tip? Share with Coderwall community!

Post
Post a tip
Did you know?

JavaScript on a page runs with the privileges of that origin. One altered library, tag manager, or snippet can read inputs, change what people see, and call your APIs as the user.

Security insights from Cside