HTML
<div class="file_upload">
<button type="button">Выбрать</button>
<div>Файл не выбран</div>
<input type="file">
</div>
CSS
.file_upload{
position: relative;
overflow: hidden;
font-size: 1em; /* example */
height: 2em; /* example */
line-height: 2em /* the same as height */
}
.file_upload > button, .file_upload > div{
cursor: pointer
}
.file_upload > button{
float: right;
width: 8em; /* example */
height: 100%
}
.file_upload > div{
padding-left: 1em /* example */
}
@media only screen and ( max-width: 500px ){ /* example */
.file_upload > div{
display: none
}
.file_upload > button{
width: 100%
}
}
.file_upload input[type=file]{
position: absolute;
top: 0;
visibility: hidden
}
/* Making it beautiful */
.file_upload{
border: 1px solid #ccc;
border-radius: 3px;
box-shadow: 0 0 5px rgba(0,0,0,0.1);
transition: box-shadow 0.1s linear
}
.file_upload.focus{
box-shadow: 0 0 5px rgba(0,30,255,0.4)
}
.file_upload > button{
background: #7300df;
transition: background 0.2s;
border: 1px solid rgba(0,0,0,0.1);
border-color: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);
border-radius: 2px;
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2) inset, 0 1px 2px rgba(0, 0, 0, 0.05);
color: #fff;
text-shadow: #6200bd 0 -1px 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis
}
.file_upload:hover > button{
background: #6200bd;
text-shadow: #5d00b3 0 -1px 0
}
.file_upload:active > button{
background: #5d00b3;
box-shadow: 0 0 3px rgba(0,0,0,0.3) inset
}
JavaScript
$(function(){
var wrapper = $( ".file_upload" ),
inp = wrapper.find( "input" ),
btn = wrapper.find( "button" ),
lbl = wrapper.find( "div" );
// Crutches for the :focus style:
btn.focus(function(){
wrapper.addClass( "focus" );
}).blur(function(){
wrapper.removeClass( "focus" );
});
// Yep, it works!
btn.add( lbl ).click(function(){
inp.click();
});
var file_api = ( window.File && window.FileReader && window.FileList && window.Blob ) ? true : false;
inp.change(function(){
var file_name;
if( file_api && inp[ 0 ].files[ 0 ] )
file_name = inp[ 0 ].files[ 0 ].name;
else
file_name = inp.val().replace( "C:\\fakepath\\", '' );
if( ! file_name.length )
return;
if( lbl.is( ":visible" ) ){
lbl.text( file_name );
btn.text( "Выбрать" );
}else
btn.text( file_name );
}).change();
});
$( window ).resize(function(){
$( ".file_upload input" ).triggerHandler( "change" );
});
Полученное стилизованное поле выбора файла было успешно протестировано для всех трех способов в следующих браузерах:
FireFox 22.0 (Linux, Windows)
Opera 12.16 (Linux, Windows)
Internet Explorer 9
Chromium 27.0 (Linux)
Apple Safari (iOS 6.3.1)
Android browser (Android 2.3.6)
Android FireFox
Из плюсов всех рассмотренных в статье подходов можно выделить следующие основные:
Не используется Flash.
Элемент можно легко стилизовать средствами CSS, используя современные технологии адаптивного дизайна.
Поле можно заполнять и с клавиатуры.
Из основных минусов:
Необходимость использования JavaScript (касается всех способов).
Использование хаков CSS для «маскировочного» способа.
Необходимость писать дополнительные костыли для поля с атрибутом multiple (касается всех способов).
Некроссбраузерность — у всех способов отсутствует поддержка IE 8, а также необходимо использовать «браузерные» свойства CSS для поддержки остальных «старичков».
Решение на JavaScript не поддерживается всеми версиями Internet Explorer, а также некоторыми старыми версиями других популярных браузеров (хотя ими уже практически никто и не пользуется).