Nice file upload button dude!

 

Thanks – glad you like it! Over the years I’ve been constantly frustrated that you can’t apply CSS styles to a file upload button. It pains me to have created a lovely looking web page, with an ugly, outdated button from the ’90s in the middle of it… So with a little bit of CSS, a sprinkling of JQuery, and the help of an awesome CSS button generator (CSSButtonGenerator.com) I’ve made the following file-upload button:

Choose file
No file selected

Looks a bit nicer than the default (ugly) button doesn’t it:

The trick is to nest the default (ugly) button within a div that’s styled to look like a (nice) button, and then hide the default (ugly) file upload button by setting its CSS opacity to zero. When you click on the (nice) button, you are actually clicking on the default (ugly) button, and triggering the file upload process like normal!

Here’s the html for the button. You can see the default ‘input’ button is nested within the override button div:

<div class="file-upload-container">
<div class="file-upload-override-button left">
Choose file
<input type="file" class="file-upload-button" id="file-upload-button"/>
</div>
<div class="file-upload-filename left" id="file-upload-filename">No file selected</div>
<div class="both"></div>
</div>

Now you need to make the ugly button bigger than the nice button so that all of the nice button div is clickable. Then set the opacity of the ugly button to zero, and hide any of the ugly button from spilling outside the nice button div by using overflow:hidden. You will also need to set cursor:pointer for the nice button div, to mimic the ‘buttonability’ of it.

The CSS looks something like this (I’ve removed all the styles for the nice button to make it more readable, but left the critical elements in there):

.left {
float: left;
}
.both {
clear: both;
}
.file-upload-container {
width:400px;
border: 1px solid #efefef;
padding:10px;
border-radius: 6px;
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
background: #fbfbfa;
}
.file-upload-override-button {
position: relative;
overflow: hidden;
cursor: pointer;
background-color:#79bbff;
}
.file-upload-override-button:hover {
background-color:#378de5;
}
.file-upload-override-button:active {
position:relative; top:1px;
}
.file-upload-button {
position: absolute;
height: 50px;
top: -10px;
left: -10px;
cursor: pointer;
opacity: 0;
filter:alpha(opacity=0);
}
.file-upload-filename {
margin-left: 10px;
height: auto;
padding: 8px;
}

Finally you will need to capture the name of the file the user chooses to upload, and display that next to the (nice) button to fully replicate the file-upload functionality. This can be done with a bit of JQuery, using the Change() event handler. You will also need to strip out the irrelevant bit of the filename before you display it, to make it look nice. (Note – when you’re doing this through a hosted website the browser adds a fake filepath "C:fakepath" to your file – nice eh?).

You will need to reference a JQuery file in your page for this to work. I’m using JQuery v.1.8.3 (as anything higher will mess up other functions in this blog theme), so my script tag looks like this:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

The javascript to grab the filename will look something this:

<script>
$("#file-upload-button").change(function () {
var fileName = $(this).val().replace('C:\\fakepath\\', '');
$("#file-upload-filename").html(fileName);
});
</script>

There you go – you can now have a button that looks nearly as awesome as mine! Let me know if this works for you, or if you have any questions or improvements!

Posted in Code, Web development Tagged with: , , , ,

About Maff

Maff Rigby

I'm a certified .Net, Umbraco and AngularJS freelance developer with over 15 years experience in the IT industry. As well as writing code I love to teach; I run a number of workshops and 1-1 coaching sessions on Angular JS and Umbraco, and share what I know and learn here!

I’m social (ish)

Connect with me on LinkedIn, follow me on Twitter, or fail to find me on Facebook.