Пример простой кастомизации поля загрузки файлов (input file)
Проблема стилизации поля типа file связана с тем, что на нем невозможно инициировать клик. То есть мы не можем просто взять и сделать document.dispatchEvent(‘click’)
на input file, пользователь должен сам совершить этот клик. Также поля данного типа, как и некоторые другие, практически не поддаются стилизации через CSS.
Если стилизовать input file нельзя, значит его в любом случае нужно прятать, а кликать по нему каким-то другим способом. И здесь вы удивитесь, какое количество способов, нередко безумных, было придумано. Я рассмотрю, на мой взгляд, самый адекватный и семантичный. Остальные легко найти в интернете, если интересно.
Способ похож на тот, что используется для кастомизации checkbox и radio кнопок. Мы будем скрывать поле и использовать элемент <label>
с параметром for=""
, что позволит инициировать открытие окна выбора файла. То есть мы решаем главную проблему – клик по полю, которого нет или которое скрыто. Увы, в отличии от решения для чекбоксов, обойтись только CSS не получится. Часть решения подразумевает использование JavaScript.
html разметка:
<div class="field-file"> <input id="file" class="field-file__input" type="file" name="uploadFile"/> <label class="field-file__label" for="file"> <i class="field-file__icon"></i> <span class="field-file__label--text">Выберите файл для загрузки</span> </label> </div>
Иконка добавлена для красоты. В действительности, для решения задачи достаточно контейнера, которым выступает div.field-file
, поля формы input[type=”file”]. field-file__input
и следом label.field-file__label
. Тэг label
обязательно должен идти после input, чтобы у нас была возможность реагировать на фокус поля без лишнего JS кода. При такой очередности тэгов можно обойтись CSS селекторами отношения +
или ~
.
Теперь CSS. Сначала прячем input file:
.field-file__input { position: absolute; opacity: 0; top: 0; right: 100%; }
Не прячем через disaplay: none
или visibility: hidden
, так как в некоторых браузерах или отдельных их версиях эти свойства станут причиной того, что на сервер не будет передаваться значение поля.
С дополнительными стилями, которые напрямую не относятся к решению задачи, это будет выглядеть следующим образом:

На текущий момент кастомный элемент позволяет выбрать файл для загрузки. Можно даже добавить некоторую реакцию на действия пользователя, используя для этого CSS селектор вида:
.field-file__input:focus ~ .field-file__label { color: #6979F8; } .field-file__input:focus ~ .field-file__label .field-file__icon { border-color: #3444c3; }
Это работает за счет порядка и связи тэгов label и input. Но вряд ли этого достаточно для того, чтобы назвать вашу форму отзывчивой. Как минимум, пользователь должен видеть, какой файл он выбрал. Именно так ведет себя стандартный input file. Добавим JavaScript код:
document.getElementById('file').addEventListener('change', function (e) { // Проверяем, что только 1 файл был выбран if (this.files && this.files.length == 1) { const textContainer = this.nextElementSibling.querySelector('.field-file__label--text'); const fileName = e.target.value.split('\\').pop(); if (textContainer) { textContainer.textContent = fileName || 'Выберите файл для загрузки'; return true; } } return false; });
Это не готовое решение, а лишь демонстрация того, как можно работать с данным типом поля с помощью JavaScript. Пока мы просто показали имя выбранного файла вместо строки «Выберите файл для загрузки», отображаемой по умолчанию. Но нередко этого достаточно и в реальных задачах.
Живой пример http://wmate.ru/wp-content/demo/4/84/index.html
Пока нет комментариев