Blog. Just Blog

Кроссбраузерная стилизация input type="file" с помощью CSS

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Продолжаем тему извечного противостояния дизайнеров и верстальщиков. Основной конфликт возникает тогда, когда дизайнер рисует картинку сайта так, как нужно заказчику, а потом верстальщику приходится адаптировать под это изображение различные элементы HTML. Один из самых сложных для стилизации элементов - это поле выбора файлов, элемент input с типом file. В качестве наглядного примера, вот как он отображается в различных браузерах:

Поле input type="file" в разных браузерах
Поле input type="file" в разных браузерах

Дополнительную сложность создает то, что это поле попадает под различные правила безопасности браузеров, поэтому его нельзя, например, заменить каким-нибудь стилизованным div, нельзя обернуть тегом label, нельзя напрямую присвоить значение с помощью скриптов или вызвать окно выбора файла, сэмулировав нажатие через element.click(). А в некоторых браузерах даже нельзя сделать поле выбора файлов скрытым, так как после отправки формы его значение не будет передано на сервер. В разных интернетах я встречал попытки сделать кроссбраузерное решение, но все они, на самом деле, не универсальные и ограничиваются конкретными браузерами.

Когда мне понадобилось решить эту проблему, я решил воспользоваться уже проверенным трюком, при котором нужный элемент помещается внутрь блока div с фиксированными размерами и фоновым изображением, а самому же элементу присваивается атрибут "прозрачный". Не скрытый, а именно полностью прозрачный. Еще немного пришлось пошаманить, чтобы в границах родительского div'а оказалась область input, отвечающая на клик мышкой и открывающая окно выбора файла. Для этого был максимально увеличен шрифт и высота самого input'а. HTML-код получается простейший:
  1. <div class="input_file">
  2.     <input type="file" size="1" name="uploaded_file" />
  3. </div>
CSS-код получается не совсем валидный за счет использования фильтров браузера Internet Explorer, но это плата за кроссбраузерность. В крайнем случае, если требуется стопроцентное прохождение валидатора, можно выставлять этот атрибут динамически средствами JavaScript или загружать отдельную таблицу стилей для IE.
  1. .input_file {
  2.     width210px;
  3.     height70px;
  4.     backgroundurl('upload_select.png'no-repeat;
  5.     cursorpointer;
  6.     overflowhidden;
  7.     padding0;
  8. }
  9. .input_file input {
  10.     opacity0;
  11.     filteralpha(opacity:0);
  12.     font-size200px;
  13.     height200px;
  14.     padding0;
  15.     margin0 0 0 -450px;
  16.     border0 none;
  17.     cursorpointer;
  18. }
Теперь на экране мы видим только стилизованную кнопку, при клике на которую открывается окно выбора файлов. Поле input для выбора файлов не отображается, но при этом прекрасно работает. Небольшая проблема остается еще в том, что некоторые браузеры игнорируют стиль курсора, и над полем input все равно отображают его как текстовый. Но, как мне кажется, на это можно не обращать внимания, хотя знать об этом нелишне.

На этом можно было бы и закончить, но в некоторых случаях может понадобиться имя выбранного файла, например, чтобы до отправки формы мы могли выполнить предварительную проверку, если ожидается файл определенного типа. Или же, например, чтобы пользователь мог проверить, тот ли файл он загружает. В обычном поле input пользователь его и так видит, а в нашем стилизованном - нет. Для этого добавим обработчик на событие onchange, HTML-код немного дополнится:
  1. <input type="file" size="1" name="uploaded_file" id="uploaded_file"
  2.  onchange="file_selected();" />
  3. <div id="file_name"></div>
  4. <div id="file_size"></div>
и добавится вот такой скрипт:
  1. <script type="text/javascript">
  2. function file_selected() {
  3.   try {
  4.     var file document.getElementById('uploaded_file').files[0];
  5.     if (file) {
  6.       var file_size 0;
  7.       if (file.size 1024 1024) {
  8.         file_size = (Math.round(file.size*100/(1024*1024))/100).toString() + 'MB';
  9.       }
  10.       else {
  11.         file_size = (Math.round(file.size*100/1024)/100).toString() + 'KB';
  12.       }
  13.       document.getElementById('file_name').innerHTML 'Name: ' file.name;
  14.       document.getElementById('file_size').innerHTML 'Size: ' file_size;
  15.     }
  16.   }
  17.   catch(e) {
  18.     var file document.getElementById('uploaded_file').value;
  19.     file file.replace(/\\/g"/").split('/').pop();
  20.     document.getElementById('file_name').innerHTML 'Name: ' file;
  21.   }
  22. }
  23. </script>
Некоторые браузеры предоставляют расширенный доступ к свойствам файла в поле input, для таких браузеров можно получить не только имя файла, но и его размер. Соответственно, такая расширенная информация и будет отображаться. Для остальных браузеров мы просто будем показывать имя выбранного файла, это значение всегда доступно через свойство value поля input.

Готовый пример формы со стилизованным полем выбора файла и его обработкой, вы можете посмотреть на демонстрационной странице.

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 9887 | Комментариев: 3

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Иван (14.09.2017 в 21:00):
Большое спасибооо.
Алексей (02.06.2016 в 05:36):
Спасибо. Всё понадобилось.
Но себе ещё и превьюху классную сделали Хд (которую удалось стащить с js с помощью исходного кода)
X-Wing Top Ace (13.04.2015 в 10:11):
Цитатавот как он отображается в различных браузерах

И в программе для их скачивания (предпоследний пример). ;))))

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2017
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0069 сек.) / Память: 4.5 Mb
Наверх