Last active
December 25, 2015 17:59
-
-
Save jdfm/7016851 to your computer and use it in GitHub Desktop.
Minimal JS, crossbrowser, styled input[type="file"] with simple markup.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<!-- | |
Minimal JS, crossbrowser, styled input[type="file"] with simple markup. | |
Tested working in IE[>=7], FF[24], O[16], C[30], S[6.0.5]; Should work in | |
all browsers that support opening a file browser via a label associated | |
to an input[type="file"]. Some adjustments might be necessary for IE[6] | |
support. | |
Tested using html5 doctype. Further testing is necessary to ensure proper | |
behaviour for others. | |
Initially I thought no JS was needed, but it seems that you have no way of | |
showing feedback when the user actually selects a file. I tried to use | |
this selector (with corresponding markup): | |
.file-input-view > input[type="file"][value=""] + label; | |
to change the aspect of the button somehow, but that didn't work because | |
the value in the document remains unchanged. | |
--> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<title>Styled Input[type="file"]</title> | |
<style> | |
.file-input-view { | |
background:gray; | |
color:white; | |
/* IE7: having a relative axis will be useful for when we shift the | |
input left because of the border sizes that get applied | |
to it's text box portion */ | |
position:relative; | |
/* remove unnecessary spacing */ | |
margin:0; | |
padding:0; | |
/* set the size of the button */ | |
display:block; | |
width:228px; | |
height:34px; | |
/* we'll be using the full width and height, anything | |
extra should be hidden */ | |
overflow:hidden; | |
} | |
.file-input-view:hover, | |
.file-input-view > label:hover { | |
background:silver; | |
color:black; | |
} | |
/* This will not work in IE7. I have no idea how to fix this. */ | |
.file-input-view:active, | |
.file-input-view > label:active { | |
background:black; | |
color:white; | |
} | |
.file-input-view > input[type="file"] { | |
/* we're going to be using the div and the label for our visual | |
styling purposes, so make the actual input invisible */ | |
-moz-opacity:0; | |
-o-opacity:0; | |
-webkit-opacity:0; | |
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; | |
filter: alpha(opacity=0); | |
opacity:0; | |
/* place the input below the label */ | |
position:absolute; | |
z-index:1; | |
/* make the button look clickable */ | |
cursor:pointer; | |
/* IE7/8 specific styles */ | |
/* IE7: removes the width from the text box. | |
IE8: The label was being pushed upwards, by the input, | |
after clicking on it once. Setting width to | |
zero corrects this. */ | |
width:0\9; | |
/* IE7 specific styles */ | |
/* this will size both the text box and the button */ | |
*border-width:17px 114px; | |
/* place the input above the label */ | |
*z-index:2; | |
/* border-left + border-right + some little extra bit, which is the | |
spacing between the textbox and the button */ | |
*left:-233px; | |
} | |
.file-input-view > label { | |
/* place the label above the input */ | |
position:absolute; | |
z-index:2; | |
/* align label text to the horizontal center */ | |
text-align:center; | |
/* make the label look clickable */ | |
cursor:pointer; | |
/* remove any extra unnecessary spacing */ | |
margin:0; | |
padding:0; | |
/* setting the line-height to the same height as the container | |
will vertically align the text to the middle of the | |
container's vertical space */ | |
line-height:34px; | |
/* use the parent element's width and height */ | |
width:100%; | |
height:100%; | |
/* IE7: the default activated area when clicking the label is the | |
text box, which does not open the file dialog. Place the | |
label under the input. */ | |
*z-index:1; | |
} | |
.file-input-view.file-selected { | |
background:green; | |
} | |
</style> | |
</head> | |
<body> | |
<!-- Associated markup --> | |
<div class="file-input-view"> | |
<label for="file_input">Upload File</label> | |
<input type="file" id="file_input" name="file_input"> | |
</div> | |
<!-- simple script to change the visual style when a file is selected --> | |
<script> | |
// get the input | |
var fileInput = document.getElementById('file_input'); | |
// get it's parent | |
var fileInputView = fileInput.parentNode; | |
// IE7 uses a different event naming scheme, get the appropriate one | |
var eventType = 'addEventListener' in fileInput? 'change': 'onchange'; | |
// IE7 uses a different event attaching mechanism, get the appropriate one | |
var attacher = 'addEventListener' in fileInput? 'addEventListener': 'attachEvent'; | |
// cache the regexp we'll be using later on | |
var fileSelectedRE = /(?:^|\s+)file-selected(?:$|\s+)/; | |
// create the event | |
fileInput[attacher](eventType, function(e){ | |
// IE places the event object in the window | |
e = e || window.event; | |
// add or remove the file-selected class to the input view for visual feedback | |
if(!fileInput.value){ | |
fileInputView.className.replace(fileSelectedRE, ' '); | |
} else if(!fileInputView.className.match(fileSelectedRE)){ | |
fileInputView.className += ' file-selected'; | |
} | |
}, false); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment