Xiper

Нестандартные поля выбора файла

Автор: Евгений Рыжков Дата публикации:

Задача

Кроссбраузерно оформить поле выбора файла (<input type="file" />).

По умолчанию поля выбора файла в разных браузерах выглядят по разному:

input type=file в firefox в Firefox 2.0
input type=file в IE6 в IE6
input type=file в Opera в Opera 9.01
input type=file в Chrome и Safari в Chrome и Safari

А по дизайну, к примеру, нужно сделать поле оформить так:
input type=file по дизайну

Решение

Для решения задачи делаем следующее:

  • делаем поле input type="file" полностью прозрачным, чтобы скрыть оформление по умолчанию, при этом оставив работоспособным
  • подкладываем блок с фоновой картинкой оформления поля
  • т.к. поле с выбором файла у нас полностью прозрачное, чтобы пользователь увидел, чтоб файл успешно выбран, добавляем обычной текстовое поле поверх оформления и при выборе нового файла, с помощью javascript название присваиваем значению текстового поля

HTML конструкция:

<div class="type_file">
    <input type="file" size="28" class="inputFile" onchange='document.getElementById("fileName").value=this.value' />
    <div class="fonTypeFile"></div>
    <input type="text" class="inputFileVal" readonly="readonly" id="fileName" />
</div>

Зачем в поле type="file" атрибут size — «Ширина поля выбора файлов в Firefox».

CSS:

.type_file { /* блок-родитель, внутри которого будут позиционироваться остальные элементы для реализации стильного поля выбора файлов */
position: relative;
height: 26px;
}
.inputFile { /* поле type="file" */
position: absolute; /* абсолютное позиционирование, чтобы можно было совместить поле и блок с оформлением */
top: 0;
left: 0;
z-index: 2; /* z-слой должен быть больше, чем у блока с оформлением */
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0); /* делаем поле абсолютно прозрачным */
-moz-opacity: 0;
-khtml-opacity: 0;
opacity: 0;
width: 267px; /* задаем ширину для всех браузеров. Для firefox подбираем значение параметра size в поле */
}
.fonTypeFile { /* блок с оформлением */
width: 267px; /* размеры картинки для оформления */
height: 26px;
background: url(images/inputFile.png); /* картинка оформления поля */
position: absolute;
top: 0;
left: 0;
z-index: 1; /* z-слой меньше, чем у поля выбора файла */
}
.inputFileVal { /* поле, в котором будет показан результат выбора файла */
position: absolute;
top: 3px;
left: 5px;
z-index: 2;
width: 175px;
background: none;
border: none;
}

Результат. Проверено в:

Недостатки

  • CSS-код не валиден (можно обойти, если воспользоваться условными комментариями для IE6 и закрыть глаза на некоторые старые браузеры, убрав -moz-opacity и -khtml-opacity)
  • требуется javascript
  • размер кнопки выбора файла по дизайну должен примерно совпадать с размера кнопки у обычного <input type="file", т.к. нет возможности изменять ее размер

Кнопка выбора файла любого размера

update: Егор Скорняков

Например имеем задачу реализовать кнопку выбора файлов вот такого размера:

Нестандартная кнопка выбора файла

Как уже отмечено, вышеприведенный способ накладывает ограничения на размер кнопки. Но что же делать, если хочется сделать огромную кнопку выбора файлов? Кроссбраузерной кликабельной частью поля выбора файла является кнопка "Browse" или "Обзор" (в Safari и Chrome кликабельной частью является вся площадь нашего поля ), сделовательно нашей задачей будет сделать эту область большого размера.

С помошью свойства height:100%; мы можем задать большую высоту, но, к сожалению, на ширину кнопки мы повлиять не можем. Для этого нам на помошь приходит небольшая хитрость: прописываем для нашего поля например font-size: 200px; (что заставит кнопку стать больше).

Далее создаём контейнер, который будет иметь в фоне изображение нашей кнопки и обязательно контейнеру прописываем overflow: hidden; для того что бы он обрезал лишнее, внутри него абсолютно позиционируем наше поле относительно правого верхнего угла, и скрываем его с помошью прозрачности равной "0".

<div class="button"><input type="file" value="" /></div>

CSS:

.button {
width: 80px; /* размеры кноки */
height: 42px;
background: url(path-to/upload-photo.png);
overflow: hidden; /* поможет избежать выхода поля за границы кнопки */
position: relative; /* относительно этого блока будем позиционировать поле */
}
.button input {
height: 200px;
position: absolute; /* для более простого позиционирования поля */
top: 0; /* начальные координаты */
right: 0;
opacity: 0; /* само поле делаем прозрачным, чтобы показать фон кнопки */
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);
cursor: pointer;
font-size: 200px;
}

Тут вы можете Посмотреть результат.Проверено в:

Заметки

Кроссбраузерный нужный вид указателя мыши на кнопке пока не получилось добиться.