Примеры изменения вида стандартного поля для загрузки файлов (input[type=file]
) с помощью CSS и JS.
1
Стандартный вид
- HTML
- CSS
- JS/JQuery
<form method="post" enctype="multipart/form-data">
<label class="input-file">
<input type="file" name="file">
<span class="input-file-btn">Выберите файл</span>
<span class="input-file-text">Максимум 10мб</span>
</label>
</form>
HTML
.input-file {
position: relative;
display: inline-block;
}
.input-file-btn {
position: relative;
display: inline-block;
cursor: pointer;
outline: none;
text-decoration: none;
font-size: 14px;
vertical-align: middle;
color: rgb(255 255 255);
text-align: center;
border-radius: 4px;
background-color: #419152;
line-height: 22px;
height: 40px;
padding: 10px 20px;
box-sizing: border-box;
border: none;
margin: 0;
transition: background-color 0.2s;
}
.input-file-text {
padding: 0 10px;
line-height: 40px;
display: inline-block;
}
.input-file input[type=file] {
position: absolute;
z-index: -1;
opacity: 0;
display: block;
width: 0;
height: 0;
}
/* Focus */
.input-file input[type=file]:focus + .input-file-btn {
box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
}
/* Hover/active */
.input-file:hover .input-file-btn {
background-color: #59be6e;
}
.input-file:active .input-file-btn {
background-color: #2E703A;
}
/* Disabled */
.input-file input[type=file]:disabled + .input-file-btn {
background-color: #eee;
}
CSS
$('.input-file input[type=file]').on('change', function(){
let file = this.files[0];
$(this).closest('.input-file').find('.input-file-text').html(file.name);
});
JS
Результат:
2
Обычная кнопка
- HTML
- CSS
- JS/JQuery
<form method="post" enctype="multipart/form-data">
<label class="input-file">
<input type="file" name="file">
<span>Выберите файл</span>
</label>
</form>
HTML
.input-file {
position: relative;
display: inline-block;
}
.input-file span {
position: relative;
display: inline-block;
cursor: pointer;
outline: none;
text-decoration: none;
font-size: 14px;
vertical-align: middle;
color: rgb(255 255 255);
text-align: center;
border-radius: 4px;
background-color: #419152;
line-height: 22px;
height: 40px;
padding: 10px 20px;
box-sizing: border-box;
border: none;
margin: 0;
transition: background-color 0.2s;
}
.input-file input[type=file] {
position: absolute;
z-index: -1;
opacity: 0;
display: block;
width: 0;
height: 0;
}
/* Focus */
.input-file input[type=file]:focus + span {
box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
}
/* Hover/active */
.input-file:hover span {
background-color: #59be6e;
}
.input-file:active span {
background-color: #2E703A;
}
/* Disabled */
.input-file input[type=file]:disabled + span {
background-color: #eee;
}
CSS
$('.input-file input[type=file]').on('change', function(){
let file = this.files[0];
$(this).next().html(file.name);
});
JS
Результат:
3
В виде input text
- HTML
- CSS
- JS/JQuery
<form method="post" enctype="multipart/form-data">
<label class="input-file">
<span class="input-file-text" type="text"></span>
<input type="file" name="file">
<span class="input-file-btn">Выберите файл</span>
</label>
</form>
HTML
.input-file {
position: relative;
display: inline-block;
}
.input-file-text {
padding: 0 10px;
line-height: 40px;
text-align: left;
height: 40px;
display: block;
float: left;
box-sizing: border-box;
width: 200px;
border-radius: 6px 0px 0 6px;
border: 1px solid #ddd;
}
.input-file-btn {
position: relative;
display: inline-block;
cursor: pointer;
outline: none;
text-decoration: none;
font-size: 14px;
vertical-align: middle;
color: rgb(255 255 255);
text-align: center;
border-radius: 0 4px 4px 0;
background-color: #419152;
line-height: 22px;
height: 40px;
padding: 10px 20px;
box-sizing: border-box;
border: none;
margin: 0;
transition: background-color 0.2s;
}
.input-file input[type=file] {
position: absolute;
z-index: -1;
opacity: 0;
display: block;
width: 0;
height: 0;
}
/* Focus */
.input-file input[type=file]:focus + .input-file-btn {
box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
}
/* Hover/active */
.input-file:hover .input-file-btn {
background-color: #59be6e;
}
.input-file:active .input-file-btn {
background-color: #2E703A;
}
/* Disabled */
.input-file input[type=file]:disabled + .input-file-btn {
background-color: #eee;
}
CSS
$('.input-file input[type=file]').on('change', function(){
let file = this.files[0];
$(this).closest('.input-file').find('.input-file-text').html(file.name);
});
JS
Результат:
4
Input file со списком выбранных файлов
- HTML
- CSS
- JS/JQuery
<form method="post" enctype="multipart/form-data">
<div class="input-file-row">
<label class="input-file">
<input type="file" name="file[]" multiple>
<span>Выберите файл</span>
</label>
<div class="input-file-list"></div>
</div>
</form>
HTML
.input-file-row {
display: inline-block;
}
.input-file {
position: relative;
display: inline-block;
}
.input-file span {
position: relative;
display: inline-block;
cursor: pointer;
outline: none;
text-decoration: none;
font-size: 14px;
vertical-align: middle;
color: rgb(255 255 255);
text-align: center;
border-radius: 4px;
background-color: #419152;
line-height: 22px;
height: 40px;
padding: 10px 20px;
box-sizing: border-box;
border: none;
margin: 0;
transition: background-color 0.2s;
}
.input-file input[type=file] {
position: absolute;
z-index: -1;
opacity: 0;
display: block;
width: 0;
height: 0;
}
/* Focus */
.input-file input[type=file]:focus + span {
box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
}
/* Hover/Active */
.input-file:hover span {
background-color: #59be6e;
}
.input-file:active span {
background-color: #2E703A;
}
/* Disabled */
.input-file input[type=file]:disabled + span {
background-color: #eee;
}
/* Список файлов */
.input-file-list {
padding: 10px 0;
}
.input-file-list-item {
margin-bottom: 10px;
}
.input-file-list-remove {
color: red;
text-decoration: none;
display: inline-block;
margin-left: 5px;
}
CSS
var dt = new DataTransfer();
$('.input-file input[type=file]').on('change', function(){
let $files_list = $(this).closest('.input-file').next();
$files_list.empty();
for(var i = 0; i < this.files.length; i++){
let new_file_input = '<div class="input-file-list-item">' +
'<span class="input-file-list-name">' + this.files.item(i).name + '</span>' +
'<a href="#" onclick="removeFilesItem(this); return false;" class="input-file-list-remove">x</a>' +
'</div>';
$files_list.append(new_file_input);
dt.items.add(this.files.item(i));
};
this.files = dt.files;
});
function removeFilesItem(target){
let name = $(target).prev().text();
let input = $(target).closest('.input-file-row').find('input[type=file]');
$(target).closest('.input-file-list-item').remove();
for(let i = 0; i < dt.items.length; i++){
if(name === dt.items[i].getAsFile().name){
dt.items.remove(i);
}
}
input[0].files = dt.files;
}
JS
Результат:
5
Загрузка изображений с превью
- HTML
- CSS
- JS/JQuery
<form method="post" enctype="multipart/form-data">
<div class="input-file-row">
<label class="input-file">
<input type="file" name="file[]" multiple accept="image/*">
<span>Выберите файл</span>
</label>
<div class="input-file-list"></div>
</div>
</form>
HTML
.input-file-row {
display: inline-block;
}
.input-file {
position: relative;
display: inline-block;
}
.input-file span {
position: relative;
display: inline-block;
cursor: pointer;
outline: none;
text-decoration: none;
font-size: 14px;
vertical-align: middle;
color: rgb(255 255 255);
text-align: center;
border-radius: 4px;
background-color: #419152;
line-height: 22px;
height: 40px;
padding: 10px 20px;
box-sizing: border-box;
border: none;
margin: 0;
transition: background-color 0.2s;
}
.input-file input[type=file] {
position: absolute;
z-index: -1;
opacity: 0;
display: block;
width: 0;
height: 0;
}
/* Focus */
.input-file input[type=file]:focus + span {
box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
}
/* Hover/active */
.input-file:hover span {
background-color: #59be6e;
}
.input-file:active span {
background-color: #2E703A;
}
/* Disabled */
.input-file input[type=file]:disabled + span {
background-color: #eee;
}
/* Список c превью */
.input-file-list {
padding: 10px 0;
}
.input-file-list-item {
display: inline-block;
margin: 0 15px 15px;
width: 150px;
vertical-align: top;
position: relative;
}
.input-file-list-item img {
width: 150px;
}
.input-file-list-name {
text-align: center;
display: block;
font-size: 12px;
text-overflow: ellipsis;
overflow: hidden;
}
.input-file-list-remove {
color: #fff;
text-decoration: none;
display: inline-block;
position: absolute;
padding: 0;
margin: 0;
top: 5px;
right: 5px;
background: #ff0202;
width: 16px;
height: 16px;
text-align: center;
line-height: 16px;
border-radius: 50%;
}
CSS
var dt = new DataTransfer();
$('.input-file input[type=file]').on('change', function(){
let $files_list = $(this).closest('.input-file').next();
$files_list.empty();
for(var i = 0; i < this.files.length; i++){
let file = this.files.item(i);
dt.items.add(file);
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function(){
let new_file_input = '<div class="input-file-list-item">' +
'<img class="input-file-list-img" src="' + reader.result + '">' +
'<span class="input-file-list-name">' + file.name + '</span>' +
'<a href="#" onclick="removeFilesItem(this); return false;" class="input-file-list-remove">x</a>' +
'</div>';
$files_list.append(new_file_input);
}
};
this.files = dt.files;
});
function removeFilesItem(target){
let name = $(target).prev().text();
let input = $(target).closest('.input-file-row').find('input[type=file]');
$(target).closest('.input-file-list-item').remove();
for(let i = 0; i < dt.items.length; i++){
if(name === dt.items[i].getAsFile().name){
dt.items.remove(i);
}
}
input[0].files = dt.files;
}
JS
Результат:
Is it possible to change the appearance of <input type="file">
?
alex
473k199 gold badges872 silver badges978 bronze badges
asked Apr 28, 2011 at 3:40
Newbie CoderNewbie Coder
10.5k18 gold badges40 silver badges53 bronze badges
3
You can’t modify much about the input[type=file]
control itself.
Since clicking a label
element correctly paired with an input will activate/focus it, we can use a label
to trigger the OS browse dialog.
Here is how you can do it…
label {
cursor: pointer;
/* Style as you please, it will become the visible UI component. */
}
#upload-photo {
opacity: 0;
position: absolute;
z-index: -1;
}
<label for="upload-photo">Browse...</label>
<input type="file" name="photo" id="upload-photo" />
The CSS for the form control will make it appear invisible and not take up space in the document layout, but will still exist so it can be activated via the label
.
If you want to display the user’s chosen path after selection, you can listen for the change
event with JavaScript and then read the path that the browser makes available to you (for security reasons it can lie to you about the exact path). A way to make it pretty for the end user is to simply use the base name of the path that is returned (so the user simply sees the chosen filename).
There is a great guide by Tympanus for styling this.
Rory O’Kane
28.5k11 gold badges96 silver badges131 bronze badges
answered Apr 28, 2011 at 3:46
7
Something like that maybe?
<form>
<input id="fileinput" type="file" style="display:none;"/>
</form>
<button id="falseinput">El Cucaratcha, for example</button>
<span id="selected_filename">No file selected</span>
<script>
$(document).ready( function() {
$('#falseinput').click(function(){
$("#fileinput").click();
});
});
$('#fileinput').change(function() {
$('#selected_filename').text($('#fileinput')[0].files[0].name);
});
</script>
answered May 7, 2013 at 13:30
KonservinKonservin
9871 gold badge9 silver badges20 bronze badges
5
<label for="fusk">dsfdsfsd</label>
<input id="fusk" type="file" name="photo" style="display: none;">
why not? ^_^
See the example here
answered Jul 1, 2014 at 9:28
jt3kjt3k
6476 silver badges17 bronze badges
2
Easiest way..
<label>
Upload
<input type="file" style="visibility: hidden;"/>
</label>
answered May 21, 2018 at 18:00
caden311caden311
9328 silver badges20 bronze badges
1
The trick is hide the input and customize the label.
HTML:
<div class="inputfile-box">
<input type="file" id="file" class="inputfile" onchange='uploadFile(this)'>
<label for="file">
<span id="file-name" class="file-box"></span>
<span class="file-button">
<i class="fa fa-upload" aria-hidden="true"></i>
Select File
</span>
</label>
</div>
CSS:
.inputfile-box {
position: relative;
}
.inputfile {
display: none;
}
.container {
display: inline-block;
width: 100%;
}
.file-box {
display: inline-block;
width: 100%;
border: 1px solid;
padding: 5px 0px 5px 5px;
box-sizing: border-box;
height: calc(2rem - 2px);
}
.file-button {
background: red;
padding: 5px;
position: absolute;
border: 1px solid;
top: 0px;
right: 0px;
}
JS:
function uploadFile(target) {
document.getElementById("file-name").innerHTML = target.files[0].name;
}
You can check this example: https://jsfiddle.net/rjurado/hnf0zhy1/4/
answered Jan 26, 2017 at 10:38
rjurado01rjurado01
5,1783 gold badges36 silver badges44 bronze badges
0
In webkit you can try this out…
input[type="file"]::-webkit-file-upload-button{
/* style goes here */
}
answered Sep 28, 2014 at 7:14
Christopher ReidChristopher Reid
4,2382 gold badges32 silver badges70 bronze badges
1
first of all it’s a container:
<div class="upload_file_container">
Select file!
<input type="file" name="photo" />
</div>
The second, it’s a CSS style, if you want to real more customization, just keeping your eyes is open
.upload_file_container{
width:100px;
height:40px;
position:relative;
background(your img);
}
.upload_file_container input{
width:100px;
height:40px;
position:absolute;
left:0;
top:0;
cursor:pointer;
}
This example hasn’t style for text inside the button, it depends on font-size, just correct the height and padding-top values for container
answered May 27, 2012 at 23:04
1
It’s much better if you just use a <label>
, hide the <input>
, and customize the label.
HTML:
<input type="file" id="input">
<label for="input" id="label">Choose File</label>
CSS:
input#input{
display: none;
}
label#label{
/* Customize your label here */
}
answered Sep 23, 2015 at 17:10
bool3maxbool3max
2,6695 gold badges25 silver badges56 bronze badges
1
Bootstrap example
<label className="btn btn-info btn-lg">
Upload
<input type="file" style="display: none" />
</label>
answered Jun 1, 2017 at 2:15
Here is a quick pure CSS workaround (works on chrome and has a FireFox fallback included), including the file name,a label and an custom upload button, does what it should — no need for JavaScript at all! 🎉
Note: ☝ anyways, I would not use it on a real world website — if browser compatibility is a thing to you (what it should be). So it’s more kind of experimental, otherwise while time goes by, it could be that this isn’t an issue today.
.fileUploadInput {
display: grid;
grid-gap: 10px;
position: relative;
z-index: 1; }
.fileUploadInput label {
display: flex;
align-items: center;
color: setColor(primary, 0.5);
background: setColor(white);
transition: .4s ease;
font-family: arial, sans-serif;
font-size: .75em;
font-weight: regular; }
.fileUploadInput input {
position: relative;
z-index: 1;
padding: 0 gap(m);
width: 100%;
height: 50px;
border: 1px solid #323262;
border-radius: 3px;
font-family: arial, sans-serif;
font-size: 1rem;
user-select: none;
cursor: pointer;
font-weight: regular; }
.fileUploadInput input[type="file"] {
padding: 0 gap(m); }
.fileUploadInput input[type="file"]::-webkit-file-upload-button {
visibility: hidden;
margin-left: 10px;
padding: 0;
height: 50px;
width: 0; }
.fileUploadInput button {
position: absolute;
right: 0;
bottom: 0;
width: 50px;
height: 50px;
line-height: 0;
user-select: none;
color: white;
background-color: #323262;
border-radius: 0 3px 3px 0;
font-family: arial, sans-serif;
font-size: 1rem;
font-weight: 800; }
.fileUploadInput button svg {
width: auto;
height: 50%; }
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
border: 0px;
outline: 0;
background-repeat: no-repeat;
appearance: none;
border-radius: 0;
vertical-align: middle;
font-weight: inherit;
font-style: inherit;
font-family: inherit;
text-decoration: none;
list-style: none;
user-select: text;
line-height: 1.333em; }
body {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100vh;
background: rgba(66, 50, 98, 0.05); }
.container {
padding: 25px;
box-shadow: 0 0 20px rgba(66, 50, 98, 0.35);
border: 1px solid #eaeaea;
border-radius: 3px;
background: white; }
@-moz-document url-prefix() {
.fileUploadInput button{
display: none
}
}
<!-- Author: Ali Soueidan-->
<!-- Author URI: https//: www.alisoueidan.com-->
<div class="container">
<div class="fileUploadInput">
<label>✨ Upload File</label>
<input type="file" />
<button>+</button></div>
</div>
answered Sep 27, 2019 at 10:54
2
to show path of selected file you can try this
on html :
<div class="fileinputs">
<input type="file" class="file">
</div>
and in javascript :
var fakeFileUpload = document.createElement('div');
fakeFileUpload.className = 'fakefile';
var image = document.createElement('div');
image.className='fakebtn';
image.innerHTML = 'browse';
fakeFileUpload.appendChild(image);
fakeFileUpload.appendChild(document.createElement('input'));
var x = document.getElementsByTagName('input');
for (var i=0;i<x.length;i++) {
if (x[i].type != 'file') continue;
if (x[i].parentNode.className != 'fileinputs') continue;
x[i].className = 'file hidden';
var clone = fakeFileUpload.cloneNode(true);
x[i].parentNode.appendChild(clone);
x[i].relatedElement = clone.getElementsByTagName('input')[0];
x[i].onchange = x[i].onmouseout = function () {
this.relatedElement.value = this.value;
}
}
and style :
div.fileinputs {
position: relative;
height: 30px;
width: 370px;
}
input.file.hidden {
position: relative;
text-align: right;
-moz-opacity: 0;
filter: alpha(opacity: 0);
opacity: 0;
z-index: 2;
}
div.fakefile {
position: absolute;
top: 0px;
left: 0px;
right: 0;
width: 370px;
padding: 0;
margin: 0;
z-index: 1;
line-height: 90%;
}
div.fakefile input {
margin-bottom: 5px;
margin-left: 0;
border: none;
box-shadow: 0px 0px 2px 1px #ccc;
padding: 4px;
width: 241px;
height: 20px;
}
div.fakefile .fakebtn{
width: 150px;
background: #eb5a41;
z-index: 10;
font-family: roya-bold;
border: none;
padding: 5px 15px;
font-size: 18px;
text-align: center;
cursor: pointer;
-webkit-transition: all 0.4s ease;
-moz-transition: all 0.4s ease;
-o-transition: all 0.4s ease;
-ms-transition: all 0.4s ease;
transition: all 0.4s ease;
display: inline;
margin-left: 3px;
}
div.fileinputs input[type="file"]:hover + div .fakebtn{
background: #DA472E;
}
div.fileinputs input[type="file"] {
opacity: 0;
position: absolute;
top: -6px;
right: 0px;
z-index: 20;
width: 102px;
height: 40px;
cursor: pointer;
}
answered Aug 12, 2015 at 6:51
saghar.fadaeisaghar.fadaei
3,0651 gold badge16 silver badges10 bronze badges
0
Here is one way which I like because it makes the input fill out the whole container. The trick is the «font-size: 100px», and it need to go with the «overflow: hidden» and the relative position.
<div id="upload-file-container" >
<input type="file" />
</div>
#upload-file-container {
width: 200px;
height: 50px;
position: relative;
border: dashed 1px black;
overflow: hidden;
}
#upload-file-container input[type="file"]
{
margin: 0;
opacity: 0;
font-size: 100px;
}
answered Jun 10, 2013 at 6:16
VanjaVanja
4,3153 gold badges25 silver badges22 bronze badges
1
I went for this option which clarifies how to fully customize the browse button by including an handler of the uploaded file name, also customized.
It adds additional fields and client-side controls on them just to show how to include the browse in a «real» form, not just a standalone.
Here’s the codepen: http://codepen.io/emiemi/pen/zxNXWR
JS:
//click on our custom btn triggers a click on the hidden actual file input
$("#btnup").click(function(){
$("#fileup").click();
});
//changes on the three fields (input, tit,and name) trigger a control which checks if the 3 fields are all filled and if file field is valid (an image is uploaded)
$('#fileup').change(function(){
var formDOMObj = document.upload;
//here we assign tu our text field #fileup the name of the selected file
var res=$('#fileup').val();
var arr = res.split("\");
//if file is not valid we show the error icon and the red alert
if (formDOMObj.fileup.value.indexOf(".jpg") == -1 && formDOMObj.fileup.value.indexOf(".png") == -1 && formDOMObj.fileup.value.indexOf(".jpeg") == -1 && formDOMObj.fileup.value.indexOf(".bmp") == -1 && formDOMObj.fileup.value.indexOf(".JPG") == -1 && formDOMObj.fileup.value.indexOf(".PNG") == -1 && formDOMObj.fileup.value.indexOf(".JPEG") == -1 && formDOMObj.fileup.value.indexOf(".BMP") == -1){
$( ".imgupload" ).hide("slow");
$( ".imguploadok" ).hide("slow");
$( ".imguploadstop" ).show("slow");
$('#nomefile').css({"color":"red","font-weight":700});
$('#nomefile').html("The file "+arr.slice(-1)[0]+" is not an image!");
$( "#bottone" ).hide();
$( "#fakebtn" ).show();
}else{
//if file is valid we show the green alert
$( ".imgupload" ).hide("slow");
$( ".imguploadstop" ).hide("slow");
$( ".imguploadok" ).show("slow");
$('#nomefile').html(arr.slice(-1)[0]);
$('#nomefile').css({"color":"green","font-weight":700});
if (formDOMObj.nome.value!=""&&formDOMObj.tit.value!=""&&formDOMObj.fileup.value!=""){
//if all three fields are valid the fake input btn is hidden and the actual one i s finally hown
$( "#fakebtn" ).hide();
$( "#bottone" ).show();
}
}
});
$('#nome').change(function(){
//same as file change but on name field
var formDOMObj = document.upload;
if (formDOMObj.nome.value!=""&&formDOMObj.tit.value!=""&&formDOMObj.fileup.value!=""){
$( "#fakebtn" ).hide();
$( "#bottone" ).show();
}else{
$( "#bottone" ).hide();
$( "#fakebtn" ).show();
}
});
$('#tit').change(function(){
//same as file change but on tit field
var formDOMObj = document.upload;
if (formDOMObj.nome.value!=""&&formDOMObj.tit.value!=""&&formDOMObj.fileup.value!=""){
$( "#fakebtn" ).hide();
$( "#bottone" ).show();
}else{
$( "#bottone" ).hide();
$( "#fakebtn" ).show();
}
});
HTML:
<form name="upload" method="post" action="/" enctype="multipart/form-data" accept-charset="utf-8">
<div class="row">
<div class="col-md-6 center">
<!--this is the actual file input, s hidden beacause we wanna use our custom one-->
<input type="file" value="" class="hidden" name="fileup" id="fileup">
<div class="btn-container">
<!--the three icons: default, ok file (img), error file (not an img)-->
<h1 class="imgupload"><i class="fa fa-file-image-o"></i></h1>
<h1 class="imguploadok"><i class="fa fa-check"></i></h1>
<h1 class="imguploadstop"><i class="fa fa-times"></i></h1>
<!--this field changes dinamically displaying the filename we are trying to upload-->
<p id="nomefile">Only pics allowed! (jpg,jpeg,bmp,png)</p>
<!--our custom btn which triggers the actual hidden one-->
<button type="button" id="btnup" class="btn btn-primary btn-lg">Browse for your pic!</button>
</div>
</div>
<!--additional fields-->
<div class="col-md-6">
<div class="row">
<div class="form-group" id="top">
<div class="col-md-12">
<input type="text" maxlength="100" class="form-control" name="nome" id="nome" placeholder="Your Name">
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<div class="col-md-12">
<input type="text" maxlength="50" class="form-control" name="tit" id="tit" placeholder="I am rubber, you are glue">
</div>
</div>
</div>
<div class="row">
<div class="col-md-8">
<p class="white">All fields are mandatory</p>
</div>
<div class="col-md-4">
<!--the defauld disabled btn and the actual one shown only if the three fields are valid-->
<input type="submit" value="Submit!" class="btn btn-primary" id="bottone" style="padding-left:50px; padding-right:50px; display:none;">
<button type="button" class="btn btn-default" disabled="disabled" id="fakebtn" style="padding-left:40px; padding-right:40px;">Submit! <i class="fa fa-minus-circle"></i></button>
</div>
</div>
</div>
</div>
answered Jan 12, 2015 at 14:03
Emi-CEmi-C
3,5221 gold badge15 silver badges15 bronze badges
$(document).ready(function () {
$(document).mousemove(function () {
$('#myList').css('display', 'block');
$("#seebtn").css('display', 'none');
$("#hidebtn").css('display', 'none');
$('#displayFileNames').html('');
$("#myList").html('');
var fileArray1 = document.getElementsByClassName('file-input');
for (var i = 0; i < fileArray1.length; i++) {
var files = fileArray1[i].files;
for (var j = 0; j < files.length; j++) {
$("#myList").append("<li style='color:black'>" + files[j].name + "</li>");
}
};
if (($("#myList").html()) != '') {
$('#unselect').css('display', 'block');
$('#divforfile').css('color', 'green');
$('#attach').css('color', 'green');
$('#displayFileNames').html($("#myList").children().length + ' ' + 'files selezionato');
};
if (($("#myList").html()) == '') {
$('#divforfile').css('color', 'black');
$('#attach').css('color', 'black');
$('#displayFileNames').append('Nessun File Selezionato');
};
});
});
function choosefiles(obj) {
$(obj).hide();
$('#myList').css('display', 'none');
$('#hidebtn').css('display', 'none');
$("#seebtn").css('display', 'none');
$('#unselect').css('display', 'none');
$("#upload-form").append("<input class='file-input inputs' type='file' onclick='choosefiles(this)' name='file[]' multiple='multiple' />");
$('#displayFileNames').html('');
}
$(document).ready(function () {
$('#unselect').click(function () {
$('#hidebtn').css('display', 'none');
$("#seebtn").css('display', 'none');
$('#displayFileNames').html('');
$("#myList").html('');
$('#myFileInput').val('');
document.getElementById('upload-form').reset();
$('#unselect').css('display', 'none');
$('#divforfile').css('color', 'black');
$('#attach').css('color', 'black');
});
});
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
.divs {
position: absolute;
display: inline-block;
background-color: #fff;
}
.inputs {
position: absolute;
left: 0px;
height: 2%;
width: 15%;
opacity: 0;
background: #00f;
z-index: 100;
}
.icons {
position: absolute;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<form id='upload-form' action='' method='post' enctype='multipart/form-data'>
<div class="divs" id="divforfile" style="color:black">
<input id='myFileInput' class='file-input inputs' type='file' name='file[]' onclick="choosefiles(this)" multiple='multiple' />
<i class="material-icons" id="attach" style="font-size:21px;color:black">attach_file</i><label>Allegati</label>
</div>
</form>
<br />
</div>
<br />
<div>
<button style="border:none; background-color:white; color:black; display:none" id="seebtn"><p>Files ▼</p></button>
<button style="border:none; background-color:white; color:black; display:none" id="hidebtn"><p>Files ▲</p></button>
<button type="button" class="close" aria-label="Close" id="unselect" style="display:none;float:left">
<span style="color:red">×</span>
</button>
<div id="displayFileNames">
</div>
<ul id="myList"></ul>
</div>
This is my fully functional customerized file upload/Attachment using jquery & javascript (Visual studio). This will be useful !
Code will be available at the comment section !
Link : https://youtu.be/It38OzMAeig
Enjoy
$(document).ready(function () {
$(document).mousemove(function () {
$('#myList').css('display', 'block');
$("#seebtn").css('display', 'none');
$("#hidebtn").css('display', 'none');
$('#displayFileNames').html('');
$("#myList").html('');
var fileArray1 = document.getElementsByClassName('file-input');
for (var i = 0; i < fileArray1.length; i++) {
var files = fileArray1[i].files;
for (var j = 0; j < files.length; j++) {
$("#myList").append("<li style='color:black'>" + files[j].name + "</li>");
}
};
if (($("#myList").html()) != '') {
$('#unselect').css('display', 'block');
$('#divforfile').css('color', 'green');
$('#attach').css('color', 'green');
$('#displayFileNames').html($("#myList").children().length + ' ' + 'files selezionato');
};
if (($("#myList").html()) == '') {
$('#divforfile').css('color', 'black');
$('#attach').css('color', 'black');
$('#displayFileNames').append('Nessun File Selezionato');
};
});
});
function choosefiles(obj) {
$(obj).hide();
$('#myList').css('display', 'none');
$('#hidebtn').css('display', 'none');
$("#seebtn").css('display', 'none');
$('#unselect').css('display', 'none');
$("#upload-form").append("<input class='file-input inputs' type='file' onclick='choosefiles(this)' name='file[]' multiple='multiple' />");
$('#displayFileNames').html('');
}
$(document).ready(function () {
$('#unselect').click(function () {
$('#hidebtn').css('display', 'none');
$("#seebtn").css('display', 'none');
$('#displayFileNames').html('');
$("#myList").html('');
$('#myFileInput').val('');
document.getElementById('upload-form').reset();
$('#unselect').css('display', 'none');
$('#divforfile').css('color', 'black');
$('#attach').css('color', 'black');
});
});
<style>
.divs {
position: absolute;
display: inline-block;
background-color: #fff;
}
.inputs {
position: absolute;
left: 0px;
height: 2%;
width: 15%;
opacity: 0;
background: #00f;
z-index: 100;
}
.icons {
position: absolute;
}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<div>
<form id='upload-form' action='' method='post' enctype='multipart/form-data'>
<div class="divs" id="divforfile" style="color:black">
<input id='myFileInput' class='file-input inputs' type='file' name='file[]' onclick="choosefiles(this)" multiple='multiple' />
<i class="material-icons" id="attach" style="font-size:21px;color:black">attach_file</i><label>Allegati</label>
</div>
</form>
<br />
</div>
<br />
<div>
<button style="border:none; background-color:white; color:black; display:none" id="seebtn"><p>Files ▼</p></button>
<button style="border:none; background-color:white; color:black; display:none" id="hidebtn"><p>Files ▲</p></button>
<button type="button" class="close" aria-label="Close" id="unselect" style="display:none;float:left">
<span style="color:red">×</span>
</button>
<div id="displayFileNames">
</div>
<ul id="myList"></ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
$(document).ready(function () {
$(document).mousemove(function () {
$('#myList').css('display', 'block');
$("#seebtn").css('display', 'none');
$("#hidebtn").css('display', 'none');
$('#displayFileNames').html('');
$("#myList").html('');
var fileArray1 = document.getElementsByClassName('file-input');
for (var i = 0; i < fileArray1.length; i++) {
var files = fileArray1[i].files;
for (var j = 0; j < files.length; j++) {
$("#myList").append("<li style='color:black'>" + files[j].name + "</li>");
}
};
if (($("#myList").html()) != '') {
$('#unselect').css('display', 'block');
$('#divforfile').css('color', 'green');
$('#attach').css('color', 'green');
$('#displayFileNames').html($("#myList").children().length + ' ' + 'files selezionato');
};
if (($("#myList").html()) == '') {
$('#divforfile').css('color', 'black');
$('#attach').css('color', 'black');
$('#displayFileNames').append('Nessun File Selezionato');
};
});
});
function choosefiles(obj) {
$(obj).hide();
$('#myList').css('display', 'none');
$('#hidebtn').css('display', 'none');
$("#seebtn").css('display', 'none');
$('#unselect').css('display', 'none');
$("#upload-form").append("<input class='file-input inputs' type='file' onclick='choosefiles(this)' name='file[]' multiple='multiple' />");
$('#displayFileNames').html('');
}
$(document).ready(function () {
$('#unselect').click(function () {
$('#hidebtn').css('display', 'none');
$("#seebtn").css('display', 'none');
$('#displayFileNames').html('');
$("#myList").html('');
$('#myFileInput').val('');
document.getElementById('upload-form').reset();
$('#unselect').css('display', 'none');
$('#divforfile').css('color', 'black');
$('#attach').css('color', 'black');
});
});
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
.divs {
position: absolute;
display: inline-block;
background-color: #fff;
}
.inputs {
position: absolute;
left: 0px;
height: 2%;
width: 15%;
opacity: 0;
background: #00f;
z-index: 100;
}
.icons {
position: absolute;
}
</style>
<div>
<form id='upload-form' action='' method='post' enctype='multipart/form-data'>
<div class="divs" id="divforfile" style="color:black">
<input id='myFileInput' class='file-input inputs' type='file' name='file[]' onclick="choosefiles(this)" multiple='multiple' />
<i class="material-icons" id="attach" style="font-size:21px;color:black">attach_file</i><label>Allegati</label>
</div>
</form>
<br />
</div>
<br />
<div>
<button style="border:none; background-color:white; color:black; display:none" id="seebtn"><p>Files ▼</p></button>
<button style="border:none; background-color:white; color:black; display:none" id="hidebtn"><p>Files ▲</p></button>
<button type="button" class="close" aria-label="Close" id="unselect" style="display:none;float:left">
<span style="color:red">×</span>
</button>
<div id="displayFileNames">
</div>
<ul id="myList"></ul>
</div>
answered May 24, 2018 at 10:46
You can style them, but you can’t remove the elements that are already there. If you’re creative, you can work with that and do something like this:
input[type=file] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background: #EEE;
background: linear-gradient(to top, #FFF, #DDD);
border: thin solid rgba(0,0,0, .5);
border-radius: .25em;
box-shadow: inset .25em .25em .25em rgba(255,255,255, .5), inset -.1em -.1em .1em rgba(0,0,0, 0.1);
cursor: text;
padding: .25em;
}
http://jsfiddle.net/zr1x1m2b/1/
I suggest you play around with this code, remove lines, add your own, do whatever until you get something that looks how you like!
answered Oct 24, 2014 at 19:59
Ky —Ky —
30.2k48 gold badges187 silver badges302 bronze badges
2
Just style a normal button however you want, using your favorite CSS.
Then call a simple JS function to create and link a hidden input element to your styled button. Don’t add browser-specific CSS to do the hiding part.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
button {
width : 160px;
height : 30px;
font-size : 13px;
border : none;
text-align : center;
background-color : #444;
color : #6f0;
}
button:active {
background-color : #779;
}
</style>
<button id="upload">Styled upload button!</button>
<script>
function Upload_On_Click(id, handler) {
var hidden_input = null;
document.getElementById(id).onclick = function() {hidden_input.click();}
function setup_hidden_input() {
hidden_input && hidden_input.parentNode.removeChild(hidden_input);
hidden_input = document.createElement("input");
hidden_input.setAttribute("type", "file");
hidden_input.style.visibility = "hidden";
document.querySelector("body").appendChild(hidden_input);
hidden_input.onchange = function() {
handler(hidden_input.files[0]);
setup_hidden_input();
};
}
setup_hidden_input();
}
Upload_On_Click("upload", function(file) {
console.log("GOT FILE: " + file.name);
});
</script>
Notice how the above code re-links it after every time the user chooses a file. This is important because «onchange» is only called if the user changes the filename. But you probably want to get the file every time the user provides it.
For more details, research DropZone and gmail uploads.
answered Sep 17, 2017 at 23:44
personal_cloudpersonal_cloud
3,7873 gold badges27 silver badges37 bronze badges
Here is one way I recently discovered, with a bit of jQuery
HTML Code:
<form action="">
<input type="file" name="file_upload" style="display:none" id="myFile">
<a onclick="fileUpload()"> Upload a file </a>
</form>
For the javascript/jQuery part :
<script>
function fileUpload() {
$("#myFile").click();
}
</script>
In this example, I have put an «anchor» tag to trigger the file upload. You can replace with anything you want, just remember to put the «onclick» attribute with the proper function.
Hope this helps!
P.S. : Do not forget to include jQuery from CDN or any other source
answered Feb 14, 2016 at 19:17
1
13 июня 2018, 13:23
Alex
HTML и CSS
1
53097
+1
Эта статья поможет изменить вид поля для отправки данных input[type=file],
который по умолчанию довольно невзрачный. Ниже приведены 3 примера оформления input file на все случаи жизни. Вам достаточно скопировать готовый код к себе на сайт.
Пример 1: Стилизация Input File под скрепку
attach_file
Добавить файл
HTML разметка
attach_file Добавить файл
CSS стилизация
.example-1 .form-group{padding:1em;margin:1em} .example-1 input[type=file]{outline:0;opacity:0;pointer-events:none;user-select:none} .example-1 .label{width:120px;border:2px dashed grey;border-radius:5px;display:block;padding:1.2em;transition:border 300ms ease;cursor:pointer;text-align:center} .example-1 .label i{display:block;font-size:42px;padding-bottom:16px} .example-1 .label i,.example-1 .label .title{color:grey;transition:200ms color} .example-1 .label:hover{border:2px solid #000} .example-1 .label:hover i,.example-1 .label:hover .title{color:#000}
Пример 2: Input File с иконкой
HTML разметка
CSS оформление
.example-2 .btn-tertiary{color:#555;padding:0;line-height:40px;width:300px;margin:auto;display:block;border:2px solid #555} .example-2 .btn-tertiary:hover,.example-2 .btn-tertiary:focus{color:#888;border-color:#888} .example-2 .input-file{width:.1px;height:.1px;opacity:0;overflow:hidden;position:absolute;z-index:-1} .example-2 .input-file + .js-labelFile{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0 10px;cursor:pointer} .example-2 .input-file + .js-labelFile .icon:before{content:"f093"} .example-2 .input-file + .js-labelFile.has-file .icon:before{content:"f00c";color:#5AAC7B}
JS скрипт
Данный скрипт позволяет менять внешний вид Input File (появится зеленая галочка) после того, как файл будет загружен.
(function() { 'use strict'; $('.input-file').each(function() { var $input = $(this), $label = $input.next('.js-labelFile'), labelVal = $label.html(); $input.on('change', function(element) { var fileName = ''; if (element.target.value) fileName = element.target.value.split('\').pop(); fileName ? $label.addClass('has-file').find('.js-fileName').html(fileName) : $label.removeClass('has-file').html(labelVal); }); }); })();
Пример 3: Брутальный Input File
Загрузить файл
HTML разметка
Загрузить файл
CSS стилизация
@import "https://fonts.googleapis.com/css?family=Varela+Round"; .example-3{box-sizing:border-box} .example-3{position:relative;font:1em/1.6 "Varela Round",Arial,sans-serif;color:#999;font-weight:400;max-width:25em;padding:1em;} .example-3 h2{font-weight:400} .example-3 .filupp > input[type="file"]{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0} .example-3 .filupp{position:relative;background:#242424;display:block;padding:1em;font-size:1em;width:100%;height:3.5em;color:#fff;cursor:pointer;box-shadow:0 1px 3px #0b0b0b} .example-3 .filupp:before{content:"";position:absolute;top:1.5em;right:.75em;width:2em;height:1.25em;border:3px solid #dd4040;border-top:0;text-align:center} .example-3 .filupp:after{content:"f178";font-family: FontAwesome;-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg);position:absolute;top:.65em;right:.45em;font-size:2em;color:#dd4040;line-height:0} .example-3 .filupp-file-name{width:75%;display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal}
JS скрипт
Скрипт отображает имя файла после его загрузки.
$(document).ready(function() { $('input[type="file"]').change(function(){ var value = $("input[type='file']").val(); $('.js-value').text(value); }); });
Поделиться с друзьями
Похожие статьи:
Подборка слайдеров для сайта на чистом CSS
Кнопка для сайта в стиле минимализм
Градиент для кнопок на сайте
3D текст с мультяшным эффектом на CSS
CSS анимация в стиле рентгена
Верстка блоков со стрелочками
Анимированный фон с плавающими облаками
Красивое оформление 404 страницы
Вертикальное hover hide меню для сайта на HTML и CSS
Стилизация checkbox и radio
HTML CSS JS
Стилизация Input File
Дата размещения статьи 19/04/2020 👁14238
Стилизация Input File
Сегодня будем стилизовать input type file. Т.к. стилизация тесно связана с обработкой input file на фронтенде, мы так же рассмотрим, как обработать выбранный файл и отправить на сервер. Скрипт будет работать для множества форм с возможностью не только загрузить файл при клике на кнопку, но так же перетаскиванием файла (drag-and-drop) в область загрузки. Если вам не нужен тот или иной функционал, вы легко сможете удалить часть кода.
Содержание:
- кнопка «Прикрепить файл»
- HTML, CSS
- JavaScript
- drag-and-drop загрузка файлов
- HTML, CSS
- JavaScript
- совместное использование кнопки «Прикрепить файл» и Drag-and-drop
- отправка множества input file multiple (PHP)
1. Стилизация input type file
1.1 Кнопка «Прикрепить файл» — HTML, CSS
Сначала нам необходимо создать html-разметку.
- multiple — данный атрибут необходим, если вы хотите разрешить отправку более одного файла;
- accept — в данный атрибут запишите типы файлов (MIME-типы), которые разрешены для выбора.
<form>
<input type="text" name="Ваше имя">
<input type="email" name="E-mail">
<div class="upload-file__wrapper">
<input
type="file"
name="files[]"
id="upload-file__input_1"
class="upload-file__input"
accept=".jpg, .jpeg, .png, .gif, .bmp, .doc, .docx, .xls, .xlsx, .txt, .tar, .zip, .7z, .7zip"
multiple
>
<label class="upload-file__label" for="upload-file__input_1">
<svg class="upload-file__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M286 384h-80c-14.2 1-23-10.7-24-24V192h-87.7c-17.8 0-26.7-21.5-14.1-34.1L242.3 5.7c7.5-7.5 19.8-7.5 27.3 0l152.2 152.2c11.6 11.6 3.7 33.1-13.1 34.1H320v168c0 13.3-10.7 24-24 24zm216-8v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-23-23V366c0-13.3 10.7-24 24-24h136v8c0 31 24.3 56 56 56h80c30.9 0 55-26.1 57-55v-8h135c13.3 0 24 10.6 24 24zm-124 88c0-11-9-20-19-20s-19 9-20 20 9 19 20 20 21-9 20-20zm64 0c0-12-9-20-20-20s-20 9-19 20 9 20 20 20 21-9 20-20z"></path>
</svg>
<span class="upload-file__text">Прикрепить файл</span>
</label>
</div>
<button type="submit">Отправить</button>
</form>
Скроем input и стилизуем кнопку для загрузки файла.
.upload-file__input {
opacity: 0;
position: absolute;
z-index: -1;
overflow: hidden;
width: 0.4px;
height: 0.4px;
}
.upload-file__label {
display: flex;
justify-content: center;
align-items: center;
max-width: 240px;
border: 2px dashed #150B22;
padding: 9px 49px;
border-radius: 6px;
cursor: pointer;
}
.upload-file__icon {
width: 30px;
height: auto;
margin-right: 11px;
}
.upload-file__label .upload-file__text,
.upload-file__label .upload-file__icon path {
transition: .25s ease;
}
.upload-file__label:hover .upload-file__text {
color: #58862D;
}
.upload-file__label:hover .upload-file__icon path {
fill: #58862D;
}
.upload-file__label:hover {
border: 2px dashed #58862D;
}
1.2 Кнопка «Прикрепить файл» — JavaScript
document.addEventListener("DOMContentLoaded", () => {
const forms = document.querySelectorAll("form");
const inputFile = document.querySelectorAll(".upload-file__input");
/////////// Кнопка «Прикрепить файл» ///////////
inputFile.forEach(function(el) {
let textSelector = document.querySelector(".upload-file__text");
let fileList;
// Событие выбора файла(ов)
el.addEventListener("change", function (e) {
// создаём массив файлов
fileList = [];
for (let i = 0; i < el.files.length; i++) {
fileList.push(el.files[i]);
}
// вызов функции для каждого файла
fileList.forEach(file => {
uploadFile(file);
});
});
// Проверяем размер файлов и выводим название
const uploadFile = (file) => {
// файла <5 Мб
if (file.size > 5 * 1024 * 1024) {
alert("Файл должен быть не более 5 МБ.");
return;
}
// Показ загружаемых файлов
if (file && file.length > 1) {
if ( file.length <= 4 ) {
textSelector.textContent = `Выбрано ${file.length} файла`;
}
if ( file.length > 4 ) {
textSelector.textContent = `Выбрано ${file.length} файлов`;
}
} else {
textSelector.textContent = file.name;
}
}
});
// Отправка формы на сервер
const postData = async (url, fData) => { // имеет асинхронные операции
// начало отправки
// здесь можно оповестить пользователя о начале отправки
// ждём ответ, только тогда наш код пойдёт дальше
let fetchResponse = await fetch(url, {
method: "POST",
body: fData
});
// ждём окончания операции
return await fetchResponse.text();
};
if (forms) {
forms.forEach(el => {
el.addEventListener("submit", function (e) {
e.preventDefault();
// создание объекта FormData
let fData = new FormData(this);
// Добавление файлов input type file
let file = el.querySelector(".upload-file__input");
for (let i = 0; i < (file.files.length); i++) {
fData.append("files[]", file.files[i]); // добавляем файлы в объект FormData()
}
// Отправка на сервер
postData("./mail.php", fData)
.then(fetchResponse => {
console.log("Данные успешно отправлены!");
console.log(fetchResponse);
})
.catch(function (error) {
console.log("Ошибка!");
console.log(error);
});
});
});
};
});
2. Drag-and-drop загрузка файлов
Структура останется прежней, т.к. наша первоначальная разметка вполне подойдёт для создания drag-and-drop области.
2.1 Drag-and-drop — HTML, CSS
<form>
<input type="text" name="Ваше имя">
<input type="email" name="E-mail">
<div class="upload-file__wrapper">
<input type="file" name="files" id="upload-file__input" class="upload-file__input" multiple accept="image/jpeg,image/png,image/gif">
<label class="upload-file__label" for="upload-file__input">
<svg class="upload-file__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M286 384h-80c-14.2 1-23-10.7-24-24V192h-87.7c-17.8 0-26.7-21.5-14.1-34.1L242.3 5.7c7.5-7.5 19.8-7.5 27.3 0l152.2 152.2c11.6 11.6 3.7 33.1-13.1 34.1H320v168c0 13.3-10.7 24-24 24zm216-8v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-23-23V366c0-13.3 10.7-24 24-24h136v8c0 31 24.3 56 56 56h80c30.9 0 55-26.1 57-55v-8h135c13.3 0 24 10.6 24 24zm-124 88c0-11-9-20-19-20s-19 9-20 20 9 19 20 20 21-9 20-20zm64 0c0-12-9-20-20-20s-20 9-19 20 9 20 20 20 21-9 20-20z">
</path>
</svg>
<span class="upload-file__text">Прикрепить файл</span>
</label>
</div>
<button type="submit">Отправить</button>
</form>
Улучшим юсабилити путём добавления стилей для drag-and-drop.
/* drag and drop - "hover" */
.upload-file__label.hover .upload-file__text {
color: #ffb300;
}
.upload-file__label.hover .upload-file__icon path {
fill: #ffb300;
}
.upload-file__label.hover {
border: 2px dashed #ffb300;
}
/* drag and drop - ошибка */
.upload-file__label.error .upload-file__text {
color: #d32f2f;
}
.upload-file__label.error .upload-file__icon path {
fill: #d32f2f;
}
.upload-file__label.error {
border: 2px dashed #d32f2f;
}
/* drag and drop - файл(ы) успешно перетянут(ы) */
.upload-file__label.drop .upload-file__text {
color: #388e3c;
}
.upload-file__label.drop .upload-file__icon path {
fill: #388e3c;
}
.upload-file__label.drop {
border: 2px dashed #388e3c;
}
2.2 Drag-and-drop загрузка файлов — JavaScript
Теперь напишем JavaScript для обработки событий перетаскивания файлов на веб-страницу. А уже в следующем пункте рассмотрим, как использовать кнопку добавления файла и область Drag-and-drop одновременно.
document.addEventListener("DOMContentLoaded", () => {
const forms = document.querySelectorAll("form");
/////////// Загрузка файлов при помощи «Drag-and-drop» ///////////
const dropZone = document.querySelector(".upload-file__label");
const dropZoneText = document.querySelector(".upload-file__text");
const maxFileSize = 5000000; // максимальный размер файла - 5 мб.
let uploadDragFile = "";
// Проверка поддержки «Drag-and-drop»
if (typeof (window.FileReader) == "undefined") {
dropZone.textContent = "Drag&Drop Не поддерживается браузером!";
dropZone.classList.add("error");
}
// Событие - перетаскивания файла
dropZone.ondragover = function () {
this.classList.add("hover");
return false;
};
dropZone.ondragleave = function () {
this.classList.remove("hover");
return false;
};
let uploadDragFiles = "";
dropZone.ondrop = function (e) { // Событие - файл перетащили
e.preventDefault();
this.classList.remove("hover");
this.classList.add("drop");
uploadDragFiles = e.dataTransfer.files;
// Проверка размера файла
if (uploadDragFiles[0].size > maxFileSize) {
dropZoneText.textContent = "Размер превышает допустимое значение!";
this.addClass("error");
return false;
}
// Показ загружаемых файлов
if (uploadDragFiles.length > 1) {
if (uploadDragFiles.length <= 4) {
dropZoneText.textContent = `Выбрано ${uploadDragFiles.length} файла`;
} else {
dropZoneText.textContent = `Выбрано ${uploadDragFiles.length} файлов`;
}
} else {
dropZoneText.textContent = e.dataTransfer.files[0].name;
}
}
// Отправка формы на сервер
const postData = async (url, fData) => { // имеет асинхронные операции
// начало отправки
// здесь можно оповестить пользователя о начале отправки
// ждём ответ, только тогда наш код пойдёт дальше
let fetchResponse = await fetch(url, {
method: "POST",
body: fData
});
// ждём окончания операции
return await fetchResponse.text();
};
if (forms) {
forms.forEach(el => {
el.addEventListener("submit", function (e) {
e.preventDefault();
// создание объекта FormData
let fData = new FormData(this);
// Добавление файлов input type file
let file = el.querySelector(".upload-file__input");
for (let i = 0; i < (file.files.length); i++) {
fData.append("files[]", file.files[i]); // добавляем файлы в объект FormData()
}
// Отправка на сервер
postData("./mail.php", fData)
.then(fetchResponse => {
console.log("Данные успешно отправлены!");
console.log(fetchResponse);
})
.catch(function (error) {
console.log("Ошибка!");
console.log(error);
});
});
});
};
});
3. Совместное использование кнопки «Прикрепить файл» и Drag-and-drop
Теперь рассмотрим случай, когда нам необходимо чтобы пользователь имел возможность прикрепить файл любым из этих способов.
HTML-структура и CSS останутся без изменений. Объеденим JavaScript код.
document.addEventListener("DOMContentLoaded", () => {
const forms = document.querySelectorAll("form");
for (let i = 1; i <= 4; i++) { // сюда будем помещать drug-&-drop файлы (4)
window["uploadDragFiles_"+i] = new Object();
}
document.querySelectorAll(".upload-file__wrapper").forEach(function (current_item, index) {
const inputFile = current_item.querySelector(".upload-file__input");
// создаём массив файлов
let fileList = [];
/////////// Кнопка «Прикрепить файл» ///////////
let textSelector = current_item.querySelector(".upload-file__text");
// Событие выбора файла(ов)
inputFile.addEventListener("change", function () {
fileList.push(...inputFile.files);
// console.log(inputFile.files);
// вызов функции для каждого файла
fileList.forEach(file => {
uploadFile(file);
});
});
// Проверяем размер файлов и выводим название
const uploadFile = (file) => {
// размер файла <5 Мб
if (file.size > 5 * 1024 * 1024) {
alert("Файл должен быть не более 5 МБ.");
return;
}
// Показ загружаемых файлов
if (file && fileList.length > 1) {
if (fileList.length <= 4) {
textSelector.textContent = `Выбрано ${fileList.length} файла`;
} else {
textSelector.textContent = `Выбрано ${fileList.length} файлов`;
}
} else {
textSelector.textContent = file.name;
}
fileList = [];
}
/////////// Загрузка файлов при помощи «Drag-and-drop» ///////////
// const dropZones = document.querySelectorAll(".upload-file__label");
const dropZone = current_item.querySelector(".upload-file__label");
const dropZoneText = current_item.querySelector(".upload-file__text");
const maxFileSize = 5000000; // максимальный размер файла - 5 мб.
// Проверка поддержки «Drag-and-drop»
if (typeof (window.FileReader) == "undefined") {
dropZone.textContent = "Drag&Drop Не поддерживается браузером!";
dropZone.classList.add("error");
}
// Событие - перетаскивания файла
dropZone.ondragover = function () {
this.classList.add("hover");
return false;
};
// Событие - отмена перетаскивания файла
dropZone.ondragleave = function () {
this.classList.remove("hover");
return false;
};
// Событие - файл перетащили
dropZone.addEventListener("drop", function (e) {
e.preventDefault();
this.classList.remove("hover");
this.classList.add("drop");
uploadDragFiles = e.dataTransfer.files[0]; // один файл
// Проверка размера файла
if (uploadDragFiles.size > maxFileSize) {
dropZoneText.textContent = "Размер превышает допустимое значение!";
this.addClass("error");
return false;
}
// Показ загружаемых файлов
if (uploadDragFiles.length > 1) {
if (uploadDragFiles.length <= 4) {
dropZoneText.textContent = `Выбрано ${uploadDragFiles.length} файла`;
} else {
dropZoneText.textContent = `Выбрано ${uploadDragFiles.length} файлов`;
}
} else {
dropZoneText.textContent = e.dataTransfer.files[0].name;
}
// добавляем файл в объект "uploadDragFiles_i"
window["uploadDragFiles_"+index] = uploadDragFiles;
});
});
// Отправка формы на сервер
const postData = async (url, fData) => { // имеет асинхронные операции
// начало отправки
// здесь можно сообщить пользователю о начале отправки
// ждём ответ, только тогда наш код пойдёт дальше
let fetchResponse = await fetch(url, {
method: "POST",
body: fData
});
// ждём окончания операции
return await fetchResponse.text();
};
if (forms) {
forms.forEach(el => {
el.addEventListener("submit", function (e) {
e.preventDefault();
// создание объекта FormData
let fData = new FormData(this);
// Добавление файлов input type file
el.querySelectorAll(".upload-file__input").forEach((one_file, index) => {
for (let i = 0; i < (one_file.files.length); i++) {
fData.append("files[]", one_file.files[i]); // добавляем файлы, добавленные кнопкой
}
fData.append("files[]", window["uploadDragFiles_"+index]); // добавляем drug-&-drop файлы
});
// Отправка на сервер
postData("./mail-files.php", fData)
.then(fetchResponse => {
swal({
title: "Спасибо!",
text: "Данные отправлены.",
icon: "success",
button: "Ok"
});
// console.table("Данные успешно отправлены!", fetchResponse);
el.reset(); // Очистка полей формы
document.querySelectorAll(".upload-file__text").forEach(this_text => {
this_text.textContent = "Выберите файл или перетащите в поле";
});
})
.catch(function (error) {
swal({
title: error,
icon: "error",
button: "Ok"
});
// console.table("Ошибка!", error);
});
});
});
};
});
4. Отправка множества input file multiple
Ранее мы успешно отправили все даннные формы (текстовые поля и файлы) на сервер.
Рассмотрим пример отправки multiple формы с множеством input file на почту.
<?php
$project_name = trim($_POST["project_name"]);
$admin_email = trim($_POST["admin_email"]);
$form_subject = trim($_POST["form_subject"]);
$file_attach = array();
// Если поле выбора вложения не пустое - закачиваем его на сервер
if (!empty($_FILES)) {
foreach ($_FILES["files"]["name"] as $key => $file) {
$path = __DIR__ . "/upload-files/" . $file; // путь загрузки файла
if (copy($_FILES["files"]["tmp_name"][$key], $path)) {
$file_attach[] = $path;
}
}
}
$c = true;
foreach ($_POST as $key => $value) {
if (is_array($value)) {
$value = implode(", ", $value);
}
if (
$value != "" &&
$key != "project_name" &&
$key != "admin_email" &&
$key != "form_subject" &&
$key != "file_attach"
) {
$message .= (($c = !$c) ? "<tr>" : "<tr style='background-color: #f8f8f8;'>") . "
<td style='padding: 10px; border: #e9e9e9 1px solid;'><b>$key</b></td>
<td style='padding: 10px; border: #e9e9e9 1px solid;'>$value</td>
</tr>";
}
}
$message = '<table style="width: 100%;">
<tr>
<td style="padding:10px; border:#e9e9e9 1px solid; text-align:center" colspan="2">
<big>$project_name</big>. $form_subject
</td>
</tr>
' . $message . '
</table>';
// Отправляем сообщение
if (empty($file_attach)) {
$headers = "MIME-Version: 1.0" . PHP_EOL .
"Content-Type: text/html; charset=utf-8" . PHP_EOL .
"From: " . $project_name . " <" . $admin_email . ">" . PHP_EOL .
"Reply-To: " . $admin_email . "" . PHP_EOL;
mail($admin_email, $form_subject, $message, $headers); # отправка текста
} else {
send_mail($admin_email, $form_subject, $message, $file_attach); # отправка файлов
}
// Функция для отправки сообщения с вложением
function send_mail($to, $form_subject, $html, $paths)
{
$boundary = "--" . md5(uniqid(time())); // генерируем разделитель
$headers = "MIME-Version: 1.0n";
$headers .= "Content-Type: multipart/mixed; boundary="$boundary"n";
$multipart = "--$boundaryn";
$multipart .= "Content-Type: text/html; charset='utf-8'n";
$multipart .= "Content-Transfer-Encoding: Quot-Printednn";
$multipart .= "$htmlnn";
$message_part = "";
foreach ($paths as $path) {
$fp = fopen($path, "r");
if (!$fp) {
echo "Файл $path не может быть прочитан";
exit();
}
$file = fread($fp, filesize($path));
fclose($fp);
$message_part .= "--$boundaryn";
$message_part .= "Content-Type: application/octet-streamn";
$message_part .= "Content-Transfer-Encoding: base64n";
$message_part .= "Content-Disposition: attachment; filename = "" . $path . ""nn";
$message_part .= chunk_split(base64_encode($file)) . "n";
}
$multipart .= $message_part . "--$boundary--n";
if (!mail($to, $form_subject, $multipart, $headers)) {
echo "К сожалению, письмо не отправлено";
exit();
}
}
Как Загрузить SVG в WordPress Наличие Динамически Добавленного Элемента
Надеюсь, вам понравилась данная информация. Если вам интересна тема web-разработки,
то можете следить за выходом новых статей в Telegram.
- JavaScript: Работа с Массивами
- Наличие Динамически Добавленного Элемента
- Предзагрузка Картинок — Предварительная Загрузка Изображений на JavaScript
- Стилизация Скролла
- События Формы
- Checkbox Checked — Проверка Состояния Чекбокса ✔️
tl;dr
Styling file inputs using CSS and the label
technique allows you to customize the look and feel. This technique conforms to semantics, is accessible, and cross-browser compliant. Check out the code and example below.
CSS
[type="file"] {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
overflow: hidden;
padding: 0;
position: absolute !important;
white-space: nowrap;
width: 1px;
}
[type="file"] + label {
/* File upload button styles */
}
[type="file"]:focus + label,
[type="file"] + label:hover {
/* File upload hover state button styles */
}
[type="file"]:focus + label {
/* File upload focus state button styles */
}
HTML
<input type="file" id="file" />
<label for="file">Upload</label>
Or if you prefer Sass — and who doesn’t:
SCSS
[type="file"] {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
overflow: hidden;
padding: 0;
position: absolute !important;
white-space: nowrap;
width: 1px;
+ label {
// File upload button styles
}
&:focus + label,
+ label:hover {
// File upload hover state button styles
}
&:focus + label {
// File upload focus state button styles
}
}
Styling File Inputs Demo
See the Pen Beautiful CSS-Only File Inputs by Ben Marshall (@bmarshall511) on CodePen.
Styling File Inputs Guide
I’ve spent countless hours styling file inputs using a number of different techniques out there. The end result is always the same — frustration. A common (IMO worst) technique to style file inputs is faking buttons with extra, non-semantic HTML, CSS, and JS. Dirty, dirty, dirty, not to mention the drawbacks for usability and touch. Don’t fret! There is a better way.
The Problem
Trying and failing to style a <input type="file" />
control is a twisted rite of passage in the web dev world. There’s a (very) long thread on Stack Overflow dedicated to it. The problem is every browser has a different way of implementing <input type="file" />
and few can be styled with CSS.
The label technique is a great solution to style file inputs since pressing the <label> triggers the focus event for the bound input. Since we’re dealing with file inputs, it works out as a click event. This results in the file browser pop-up and is a great semantic solution! No JavaScript, no other complex solutions like cursor position tracking, and just these two lines.
CSS File Input label
Technique
Styling clean, semantic and accessible upload buttons require two things: CSS & label
. I’ll go over how and demonstrate how a little extra JS (optional) can enhance the UX. The input file CSS possibilities are limitless once you understand how this technique works!
First, create the semantic HTML.
You’ll start with the HTML semantic for a file input. It must have a label preceding it, this will become the upload button:
HTML
<input type="file" id="file" />
<label for="file">choose a file</label>
Next, hide the native button.
Bet you’re thinking display: none
or visibility: hidden
? Nope. Those won’t work because the input value won’t be sent to the server when submitted. It’ll also be excluded out of the tab order making it no longer accessible. In order to keep it accessible, use the following CSS:
CSS
[type="file"] {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
overflow: hidden;
padding: 0;
position: absolute !important;
white-space: nowrap;
width: 1px;
}
Why 1x1px? Setting property values to zero ends up throwing the element out of tab order in some browsers. position: absolute
guarantees the element does not interfere with the sibling elements. Don’t forget when styling file inputs, accessibility is an important factor.
The fun part, styling the upload button.
Now we’ll style the file input by using the <label>
element as the upload button. From there, use your creative CSS juices on it! Check out the basic example below:
CSS
[type="file"] + label {
background-color: #000;
border-radius: 4rem;
color: #fff;
cursor: pointer;
display: inline-block;
font-family: 'Poppins', sans-serif;
font-size: 1rem;
font-weight: 700;
height: 4rem;
line-height: 4rem;
padding-left: 2rem;
padding-right: 2rem;
transition: background-color 0.3s;
}
[type="file"]:focus + label,
[type="file"] + label:hover {
background-color: #f15d22;
}
[type="file"]:focus + label {
outline: 1px dotted #000;
outline: -webkit-focus-ring-color auto 5px;
}
The complete code.
Let’s put it all together, here’s the complete code below:
CSS
[type="file"] {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
overflow: hidden;
padding: 0;
position: absolute !important;
white-space: nowrap;
width: 1px;
}
[type="file"] + label {
background-color: #000;
border-radius: 4rem;
color: #fff;
cursor: pointer;
display: inline-block;
padding-left: 2rem 4rem;
}
[type="file"]:focus + label,
[type="file"] + label:hover {
background-color: #f15d22;
}
[type="file"]:focus + label {
outline: 1px dotted #000;
}
It’s that easy! You can now adjust the styling as needed to create your own upload button to match your site styles.
The accessible part.
How do you know that an element on the website is accessible?
- Elements should communicate a feeling that you can tap or click on it.
- The cursor icon should change to an appropriate one when hovering the element.
- Tabbed keyboard navigation should be intuitive.
The label
technique covers all of these requirements.
More about keyboard navigation.
If users are unable to navigate your website using just a keyboard, you are doing something wrong. Hiding the input correctly and indicating when the element is focused (i.e. rendering [type="file"]:focus
on the label
). ensures this functionality stays intact.
-webkit-focus-ring-color: auto 5px
is a little trick for obtaining default outline looks on Chrome, Opera and Safari.
Touch Issues with FastClick
In case you’ve been using FastClick (a library for eliminating the 300ms tap-pause on touch-capable devices) and have plans to add some extra markup to the content of a label, the button won’t work as it should, unless you use pointer-events: none
, respectively:
[type="file"] + label * {
pointer-events: none;
}
Enhance the UX with JavaScript
When styling file inputs, it’s important to provide users with feedback when a file is selected for upload. When hiding the native file input, users don’t have a way to tell a file was selected.
There’s a simple fix with some JavaScript that’ll provide this functionality:
- When the user selects a file, the text of a label will become the name of the selected file.
- If there were multiple files selected, the text will tell us how many of them were selected.
Check out the example below:
HTML
<input type="file" name="file" id="file" data-multiple-caption="{count} files selected" multiple />
JS
var inputs = document.querySelectorAll( '.inputfile' );
Array.prototype.forEach.call( inputs, function( input ) {
var label = input.nextElementSibling,
labelVal = label.innerHTML;
input.addEventListener( 'change', function( e ) {
var fileName = '';
if ( this.files && this.files.length > 1 ) {
fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
} else {
fileName = e.target.value.split( '\' ).pop();
}
if ( fileName ) {
label.querySelector( 'span' ).innerHTML = fileName;
} else {
label.innerHTML = labelVal;
}
});
});
Having the native [multiple]
attribute allows users to select more than one file per upload. Whereas [data-multiple-caption]
is a fictive attribute for expressing the message if multiple files were selected. Here you can set a custom message. The use of the {count}
phrase is optional and the fragment is replaced with the number of files selected.
An interesting thing is that you can unset a value of the input by pressing the ESC button while in the file browser. This is possible only in Chrome and Opera. Therefore, we use labelVal
for storing the default value of the label and bringing it back when necessary.
[multiple]
is not supported in IE 9 and below; neither is the files property of JavaScript. For the latter case, we simply rely on value. Since it usually has a value of C:fakepathfilename.jpg
format, the split( '\' ).pop()
extracts what’s actual — the name of the file.
There is also a jQuery version of this code you can download here.
No JavaScript, no problem!
Since there is no JavaScript-less way to indicate if any files were selected, it would be better to rely on the default looks of the file input for the sake of usability.
Styling file inputs with an enhanced UX is a cinch. All we need to do is to add a .no-js
class name to the <html>
element. We’ll use JavaScript to remove it if available — that’s how we’ll determine if our JS enhancement will work.
Many frameworks like Foundation and Bootstrap already do this.
<html class="no-js">
<head>
<!-- remove this if you use Modernizr -->
<script>(function(e,t,n){var r=e.querySelectorAll("html")[0];r.className=r.className.replace(/(^|s)no-js(s|$)/,"$1js$2")})(document,window,0);</script>
</head>
</html>
.js [type="file"] {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
overflow: hidden;
padding: 0;
position: absolute !important;
white-space: nowrap;
width: 1px;
}
.no-js [type="file"] + label {
display: none;
}
Firefox Bug Fix
There’s a known Firefox bug when it comes to styling file inputs that completely ignores the input[type="file"]:focus
expression, yet :hover
and :active
work just fine — don’t ask me why. However, Firefox allows us to catch the focus
event using JavaScript. This workaround adds a class to the file input element letting us control the focus style:
JS
input.addEventListener( 'focus', function(){ input.classList.add( 'has-focus' ); });
input.addEventListener( 'blur', function(){ input.classList.remove( 'has-focus' ); });
CSS
[type="file"]:focus + label,
[type="file"].has-focus + label {
outline: 1px dotted #000;
outline: -webkit-focus-ring-color auto 5px;
}
Using a CSS framework?
Many popular CSS frameworks like Foundation and Bootstrap already have a way to customize upload buttons. Check out the examples below.
Styling File Inputs with Foundation
Customizing the file upload button in Foundation uses the same technique above. To hide the native upload button it uses the visibility class for screen readers (.show-for-sr
).
Use Foundation’s settings file to update variables to customize the button to your liking. The HTML structure follows the same pattern shown above:
<label for="file" class="button">Upload File</label><input type="file" id="file" class="show-for-sr" />
Styling File Inputs with Bootstrap
Bootstrap’s method for styling file inputs isn’t as clean or optimized as this technique or Foundations’ — just another reason I prefer Foundation over Bootstrap. It requires additional JavaScript in order for it to override the native upload button.
<div class="custom-file">
<input type="file" class="custom-file-input" id="file">
<label class="custom-file-label" for="file">Choose file</label>
</div>
This method may not be as clean, but it does provide a little more flexibility for translations:
$custom-file-text: (
en: "Browse",
es: "Elegir"
);
<div class="custom-file">
<input type="file" class="custom-file-input" id="file" lang="es">
<label class="custom-file-label" for="file">Seleccionar Archivo</label>
</div>
The :lang()
pseudo-class is used to allow for translation of the “Browse” text into other languages. Override or add entries to the $custom-file-text
Sass variable with the relevant language tag and localized strings. English strings can be customized the same way.
Styling File Input Alternatives
Like with most things in web development, there’s more than one way to skin a cat. Here’s some other popular techniques to style file inputs:
- Using Web Components to Style File Inputs by TJ VanToll
- jQuery File Upload
- jQuery FileAPI
- Kendo UI
In Conclusion
Styling file inputs is a problem web developers have been trying to solve for years. With this workaround we finally have a solid, semantic and accessible solution.
There are quite a few techniques for “customizing” the <input type="file" />
element. I tried most of them, but none was good enough to have on Readerrr (for importing feeds by uploading a file). Probably the worst technique was the one where the input element is put into a container (which imitates a button), and the input follows the cursor so that when you click anywhere on the container, you actually click the input. Sounds interesting and weird at the same time, right? Anyway, it had some unacceptable drawbacks (usability, touch).
As as result, I tried googling for an unseen solution. Once it seemed that there was nothing new, my I eyes were caught by a comment on StackOverflow. It had just a few up votes and was lost somewhere in the middle of the page, but most importantly it contained a magic word – <label>
! As you may know, pressing a label basically triggers the focus event for the bound input. Interesting thing is that, if it is a file input, it works out as a click event, resulting in opening a file browser. This is great for crafting a semantic solution.
<input type="file" name="file" id="file" class="inputfile" /> <label for="file">Choose a file</label>
So, pressing any of these two elements gives us the same result. That means that the most difficult part is… solved! No JavaScript, no other complex solutions like cursor position tracking, just these two lines. See for yourself:
Now let’s just style it and make this look like a normal button.
Hiding the <input>
First off, we need to hide the ugly duckling. CSS properties such as display: none
or visibility: hidden
will not work out. The reasons are: the input value will not be sent to the server on form submit; the input will be excluded out of tab order (you want your website to be accessible, right?). I set up a combination of CSS properties/values for hiding the input visually but keeping it visible for the browser:
.inputfile { width: 0.1px; height: 0.1px; opacity: 0; overflow: hidden; position: absolute; z-index: -1; }
I see you are wondering why width
and height
are set to 0.1px
instead of just 0px
. Setting the property values to zero ends up throwing the element out of tab party in some browsers. And position: absolute
guarantees the element does not interfere with the sibling elements.
Styling the <label>
Since the <label>
element is visually the button, you can use all of your creative CSS juices on it. I’m sticking to something very simple for now:
.inputfile + label { font-size: 1.25em; font-weight: 700; color: white; background-color: black; display: inline-block; } .inputfile:focus + label, .inputfile + label:hover { background-color: red; }
Accessibility
How do you know that an element on the website is pressable? Firstly, the element should communicate a feeling that you can tap or click on it. Secondly, the cursor icon should change to an appropriate one when hovering the element. The former we’ve solved previously, let’s solve the latter, because labels do not trigger a cursor change by default:
.inputfile + label { cursor: pointer; /* "hand" cursor */ }
Keyboard Navigation
If users are unable to navigate on your website using just a keyboard, you are doing something wrong. Hiding the input itself in a correct manner was one thing, the other is indicating when the element is focused, i.e. rendering .inputfile:focus
on the label
:
.inputfile:focus + label { outline: 1px dotted #000; outline: -webkit-focus-ring-color auto 5px; }
-webkit-focus-ring-color auto 5px
is a little trick for obtaining default outline looks on Chrome, Opera and Safari. The style in the line above is for browsers that do not understand the -webkit…
expression.
Possible Touch Issues
In case you’ve been using FastClick (a library for eliminating the 300ms tap-pause on touch-capable devices) and have plans to add some extra markup to the content of a label, the button won’t work as it should, unless you use pointer-events: none
, respectively:
<label for="file"><strong>Choose a file</strong></label>
.inputfile + label * { pointer-events: none; }
JavaScript Enhancement
Probably and hopefully the last thing missing is indicating if files were selected. The file input does usually indicate that, but in our case the input is visually hidden. Luckily, there is a way out: a tiny JavaScript enhancement. The text of a label becomes the name of the selected file. If there were multiple files selected, the text will tell us how many of them were selected.
<input type="file" name="file" id="file" class="inputfile" data-multiple-caption="{count} files selected" multiple />
var inputs = document.querySelectorAll( '.inputfile' ); Array.prototype.forEach.call( inputs, function( input ) { var label = input.nextElementSibling, labelVal = label.innerHTML; input.addEventListener( 'change', function( e ) { var fileName = ''; if( this.files && this.files.length > 1 ) fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length ); else fileName = e.target.value.split( '' ).pop(); if( fileName ) label.querySelector( 'span' ).innerHTML = fileName; else label.innerHTML = labelVal; }); });
There is also a jQuery version of this code presented in the source of the demo files. Make sure to check them out.
A little explanation:
- Having the native
[multiple]
attribute allows users to select more than one file per upload. Whereas[data-multiple-caption]
is a fictive attribute for expressing the message if multiple files were selected. Here you can set a custom message. The use of the{count}
phrase is optional and the fragment is replaced with the number of files selected. The reason I use an additional HTML attribute instead of assigning this sentence as a value for a JavaScript variable is because it’s much easier to maintain the copy when it is in one place. - HTML attribute
[multiple]
is not supported in IE 9 and below and neither is thefiles
property of JavaScript. For the latter case, we simply rely onvalue
. Since it usually has a value ofC:fakepathfilename.jpg
format, thesplit( '' ).pop()
extracts what’s actual – the name of the file. - An interesting thing is that you can unset a value of the input by pressing the ESC button while in the file browser. This is possible only in Chrome and Opera. Therefore, we use
labelVal
for storing the default value of the label and bringing it back when necessary.
This is how the final result looks like:
What if JavaScript is not available?
Since there is no JavaScript-less way to indicate if any files were selected, it would be better to rely on the default looks of the file input for the sake of usability. All we need to do is to add a .no-js
class name to the <html>
element and then use JavaScript and replace it with .js
– that’s how we will know if JavaScript is available.
<html class="no-js"> <head> <!-- remove this if you use Modernizr --> <script>(function(e,t,n){var r=e.querySelectorAll("html")[0];r.className=r.className.replace(/(^|s)no-js(s|$)/,"$1js$2")})(document,window,0);</script> </head> </html>
The CSS part accordingly:
.js .inputfile { width: 0.1px; height: 0.1px; opacity: 0; overflow: hidden; position: absolute; z-index: -1; } .no-js .inputfile + label { display: none; }
Firefox Bug
It is quite unexpected that Firefox completely ignores the input[type="file"]:focus
expression, whereas :hover
and :active
work just fine! Surprisingly, Firefox allows to catch the focus
event in JavaScript, so the workaround is adding a class to the file input element that let’s us control the focus style:
input.addEventListener( 'focus', function(){ input.classList.add( 'has-focus' ); }); input.addEventListener( 'blur', function(){ input.classList.remove( 'has-focus' ); });
.inputfile:focus + label, .inputfile.has-focus + label { outline: 1px dotted #000; outline: -webkit-focus-ring-color auto 5px; }
Check out the example styles in the demo to see how to style the file input element according to your needs. Make sure to take a look at the source code of the demo and feel free to use this technique in your projects. Happy uploading!
The icon in the demo is made by Daniel Bruce from www.flaticon.com and it is licensed under CC BY 3.0.
Здравствуйте уважаемые читатели блога webcodius.ru! Одной из самых сложных задач для верстальщика является стилизация элементов формы так, как видит их дизайнер. Тем более по умолчанию такие поля как select, checkbox или file совершенно отличаются внешне в разных браузерах. В этой статье рассмотрим способы стилизации поля для загрузки файла, чтобы оно одинаково выглядело в большинстве браузеров.
На мой взгляд, наиболее оптимальным решением будет обернуть поле input с типом file в тег label. Затем скрываем поле input file, а при клике по элементу label будет вызываться окно выбора файла.
Html — код вставки поля для загрузки файла в этом случае будет таким:
<div id="file-upload">
<label>
<input type="file" name="file" id="uploade-file">
<span>Выберите файл</span>
</label>
</div>
Далее задаем CSS стили для наших элементов:
.file-upload input[type=»file»]{
display: none;/* скрываем input file */
}
/* задаем стили кнопки выбора файла*/
.file-upload {
position: relative;
overflow: hidden;
width: 250px;
height: 40px;
background: #4169E1;
border-radius: 10px;
color: #fff;
text-align: center;
}
.file-upload:hover {
background: #1E90FF;
}
/* Растягиваем label на всю область блока .file-upload */
.file-upload label {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
cursor: pointer;
}
/* стиль текста на кнопке*/
.file-upload span {
line-height: 40px;
font-weight:bold;
}
Большинство CSS правил для класса .file-upload можно менять под Ваши нужды (такие как background, border-radius, color, width и height), так как они в основном отвечают за внешний вид кнопки выбора файла.
В результате в окне браузера мы видим стилизованную кнопку выбора файла, по клику на которой появляется окно выбора файла:
Осталась дна проблема. При выборе файла, визуально это никак не отобразиться, а хотелось бы видеть имя загружаемого файла. Это может понадобиться, что бы пользователь мог проверить, тот ли файл он загружает. В стандартном поле input file имя загружаемого файла отображается рядом с кнопкой выбора файла, а в нашем стилизованном этого нет. Для исправления этой ситуации потребуется использовать javascript.
Для начала добавим в html-код дополнительный элемент элемент div для вывода имени загружаемого файла и добавим обработчик на событие onchange:
<div class=»file-upload»>
<label>
<input type=»file» name=»file» onchange=»getFileName ();» id=»uploaded-file»>
<span>Выберите файл</span>
</label>
</div>
<div id=»file-name»></div>
Далее добавляем код javascript, который вставляет имя файла в элемент <div id=»file-name»>:
function getFileName () {
var file = document.getElementById (‘uploaded-file’).value;
file = file.replace (/\/g, «/»).split (‘/’).pop ();
document.getElementById (‘file-name’).innerHTML = ‘Имя файла: ‘ + file;
}
В результате получим такой вариант поля input file:
При выборе файла под кнопкой появляется текст с названием файла. Данный способ стилизации input file точно работает в браузерах IE9+, Chrome, Firefox, Mozilla и Opera. Кроме того многие браузеры позволяют получать размер и разрешение выбранного файла. Также можно сделать предпросмотр выбранного файла в случае если загружается картинка. Например, такой вариант:
Код к последнему примеру можно скачать по ссылке.
На этом все, до новых встреч!
HTML elements have default styles applied to them by individual browsers. These styles could vary depending on the browser, and applying your own custom styles could range from being very easy to unnecessarily complicated (sometimes impossible).
In this article we would be going through how to style file inputs, which happens to be one of those difficult elements to style using CSS.
If you’ve worked with file inputs in your application, you’d know that the default style doesn’t look so nice. Here’s an example of how it looks in chrome and firefox in case you’re wondering.
The good news is, we can fix this…the bad news is we won’t be able to use the «conventional» method.
Styling File Inputs
Let’s create a simple file input in our HTML.
<div class="file-input">
<input type="file" id="file" class="file">
<label for="file">Select file</label>
</div>
Enter fullscreen mode
Exit fullscreen mode
To style a file input, the first thing we would need to do is get rid of the default file input.
Hiding the input
.file {
opacity: 0;
width: 0.1px;
height: 0.1px;
position: absolute;
}
Enter fullscreen mode
Exit fullscreen mode
You might be thinking, why not use display: none
to hide the input. Well the problem with that is the input field would be removed from the layout and then become inaccessible to people using screen readers which would be very bad.
Another important thing to note is the label
. With file inputs, clicking on the label also opens up the file picker, so we can use that to our advantage and style the label anyway we want.
Styling the label
Now that we’ve hidden the default input, we can decide to style the label however we want. For simplicity sake, let’s just make it look like a button.
.file-input label {
display: block;
position: relative;
width: 200px;
height: 50px;
border-radius: 25px;
background: linear-gradient(40deg, #ff6ec4, #7873f5);
box-shadow: 0 4px 7px rgba(0, 0, 0, 0.4);
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-weight: bold;
cursor: pointer;
transition: transform .2s ease-out;
}
Enter fullscreen mode
Exit fullscreen mode
Accessibility
So we’ve been able to style the label to look like a button, but that’s not all. We need to add some sort of indications to the label for when people hover on the field, or try to focus on the file field using the keyboard. I’m just going to do something simple here and increase the size of the label when that happens.
input:hover + label,
input:focus + label {
transform: scale(1.02);
}
Enter fullscreen mode
Exit fullscreen mode
We can also decide to add an outline to the label on focus
input:focus + label {
outline: 1px solid #000;
outline: -webkit-focus-ring-color auto 2px;
}
Enter fullscreen mode
Exit fullscreen mode
The -webkit-focus-ring-color
is used to get the default outline look on webkit browsers like chrome or safari. For non webkit browsers, a black outline would be applied to the element.
Javascript Enhancements
We can use JavaScript to display the name and size of the file selected. This would create a slightly more natural feel to the custom field. So let’s modify our HTML and CSS a bit.
<div class="file-input">
<input type="file" id="file" class="file">
<label for="file">
Select file
<p class="file-name"></p>
</label>
</div>
Enter fullscreen mode
Exit fullscreen mode
.file-name {
position: absolute;
bottom: -35px;
left: 10px;
font-size: 0.85rem;
color: #555;
}
Enter fullscreen mode
Exit fullscreen mode
Finally, we would add an event listener to the file input and reflect the name and size of the file below the label.
const file = document.querySelector('#file');
file.addEventListener('change', (e) => {
// Get the selected file
const [file] = e.target.files;
// Get the file name and size
const { name: fileName, size } = file;
// Convert size in bytes to kilo bytes
const fileSize = (size / 1000).toFixed(2);
// Set the text content
const fileNameAndSize = `${fileName} - ${fileSize}KB`;
document.querySelector('.file-name').textContent = fileNameAndSize;
});
Enter fullscreen mode
Exit fullscreen mode
Here’s how everything looks.
And that’s it for the file input. You could decide to style this however you want to get the behavior you want, it’s up to you. Happy styling!😁😁
11 Tips That Make You a Better Typescript Programmer
1 Think in {Set}
Type is an everyday concept to programmers, but it’s surprisingly difficult to define it succinctly. I find it helpful to use Set as a conceptual model instead.
#2 Understand declared type and narrowed type
One extremely powerful typescript feature is automatic type narrowing based on control flow. This means a variable has two types associated with it at any specific point of code location: a declaration type and a narrowed type.
#3 Use discriminated union instead of optional fields
…
Read the whole post now!
Read next
PHP-like namespaces in JavaScript using Unicode identifiers
Lukas Gaucas — Jan 11
The road to Software Architecture (frontend edition)
Kate — Feb 1
Using Gleam in your Phoenix Hooks
Camilo — Jan 31
Mastering Internationalization and Localization in JavaScript: A Comprehensive Guide
sahra — Jan 31
Once unpublished, all posts by ibn_abubakre will become hidden and only accessible to themselves.
If ibn_abubakre is not suspended, they can still re-publish their posts from their dashboard.
Note:
Once unpublished, this post will become invisible to the public and only accessible to Abdulqudus Abubakre.
They can still re-publish the post if they are not suspended.
Thanks for keeping DEV Community 👩💻👨💻 safe. Here is what you can do to flag ibn_abubakre:
Make all posts by ibn_abubakre less visible
ibn_abubakre consistently posts content that violates DEV Community 👩💻👨💻’s
code of conduct because it is harassing, offensive or spammy.