Я думаю что все кто занимается версткой так или иначе сталкивались с проблемой кастомизации input[type=file]. Задача сама по себе не тривиальная, так как на прямую возможность задать стиль для данного поля нельзя. Вот и на моей профессиональной улице случился праздник, когда для одного проекта понадобилось изменить стиль отображения для стандартных полей выбора файлов. О том как я это делал я и собираюсь рассказать.
Конечно же первым делом я обратился к великому и могучему гуглу и менее великому, но в некоторых моментах не менее могучему яндексу. И что же я увидел? Конечно же огромное количество репостов двух трех статей (вот кстати ссылки на них — здесь взята основная идея и html составляющая, очень хорошая статья по теме), но все найденные решения не подходили под то что надо сделать. В общем то кастомизировать файл-инпут с сохранением функциональности и максимальной похожестью на оригинал. Начнем с HTML составляющей.
<div class="input_file">
<input type="file" name="" >
<div class="fake_file"><input type="text" class="fake_file_input">
<input type="button" value="Выбрать"></div>
</div>
* This source code was highlighted with Source Code Highlighter.
Создаем блок, в который помещаем наш файл-инпут, и еще один блок, в который помещаем замену для него, в виде текст-инпута и кнопки.
.input_file {
position: relative;
margin: 0 0 10px 0;
}
.input_file input[type=file] {
opacity: 0;
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);
position: relative;
z-index: 2;
cursor: pointer;
height: 34px;
width: 300px;
}
* This source code was highlighted with Source Code Highlighter.
Я думаю что со стилями для оберточного блока все понятно. Самое интересное в стилях для файл-инпута.
Во первых мы сделаем его полностью прозрачным, так как он нам не нужен, а спрятать его через visibility:hidden или display:none не получиться, потому что тогда мы потеряем возможность клика по этому полю. Так же тут же добавил фильтр для всеми любимого IE. Во вторых поднимем файл-инпут над другими элементами, что бы опять же иметь возможность кликнуть по нему. В третьих мы задаем высоту, так как нам нужно что бы поля которые выполняют роль заместителей перекрывались невидимым инпутом полностью (что бы пользователь не промазал случайно).
В стилях для «заменителя» стоит отметить абсолютное позиционирование, и то что данный блок располагается за файл-инпутом. В остальном же это просто стилизация (каждому по вкусам и по потребностям).
В общем то на данный момент мы имеем полностью рабочую версию, за исключением того что мы не видим имени файлов, которые мы выбрали. Вот тут к нам на помощь приходит JavaScript (я использую jQuery).
$('.input_file input[type=file]').change(function(){
var t = $(this).val();
if(t.indexOf('C:\\fakepath\\')+1)
t = t.substr(12);
var e = $(this).next().find('.fake_file_input');
e.val(t);
});
* This source code was highlighted with Source Code Highlighter.
Небольшая функция которая вызывается при изменении значения файл-инпута, в задачу которой входит вставить название файла в текст-инпут. Так как в большинстве браузеров, в целях обеспечения безопасности напрямую это сделать невозможно, точнее возможно, но подставляется C:\fakepath\, то соответственно этот fakepath обрезается, оставляя только само значение файла.
$('.clear_input').click(function(){
var a = $(this).parent();
var e = a.find('.fake_file_input');
var t = a.find('input[type=file]');
t.replaceWith('<input type="file" name="" >');
e.val('');
});
* This source code was highlighted with Source Code Highlighter.
Вторая функция предназначена для очищения значения введенного в поле, так как напрямую мы этого сделать не можем. Поступает оно просто, создает новый файл-инпут, в замен старого (опять же, в целях безопасности мы не можем менять значение файл-инпута напрямую) и очищая значения текст-инпута. Ну и для того что бы эта функция сработала, добавим ссылку
<div class="input_file">
...
<a href="#" class="clear_input">Очистить</a>
</div>
* This source code was highlighted with Source Code Highlighter.
Вот в общем то и все. Итоговый результат