J'essaie d'adapter un bouton de téléchargement de fichier à mes préférences personnelles, mais je ne pouvais trouver aucun moyen vraiment solide de le faire sans JS. J'ai trouvé deuxautre questions sur ce sujet, mais les réponses à ce sujet impliquaient JavaScript ou suggéraient approche de Quirksmode .
Mon principal problème avec cette approche de Quirksmode est que le bouton de fichier aura toujours les dimensions définies par le navigateur, de sorte qu'il ne s'adapte pas automatiquement à tout ce qui est utilisé comme bouton placé en dessous. J'ai créé du code, basé sur celui-ci, mais il occupera simplement l'espace que le bouton de fichier prendrait normalement, de sorte qu'il ne remplira pas du tout la division parent comme je le souhaite.
HTML:
<div class="myLabel">
<input type="file"/>
<span>My Label</span>
</div>
CSS:
.myLabel {
position: relative;
}
.myLabel input {
position: absolute;
z-index: 2;
opacity: 0;
width: 100%;
height: 100%;
}
Ce violon montre à quel point cette approche est assez imparfaite. Sous Chrome, cliquez sur le !!
situé sous le deuxième bouton de démonstration pour ouvrir la boîte de dialogue de fichier. Toutefois, dans tous les autres navigateurs, le bouton de fichier ne couvre pas les zones correctes du bouton.
Existe-t-il un moyen plus solide de styler le bouton de téléchargement de fichier, sans JavaScript et en utilisant de préférence le moins de code possible (le piratage informatique amenant d’autres problèmes, comme ceux du violon)?
Je publie ceci parce que (à ma grande surprise), je n'ai trouvé aucun autre endroit qui recommande cela.
Il existe un moyen très simple de le faire, sans vous limiter aux dimensions d'entrée définies par le navigateur. Utilisez simplement la balise <label>
autour d'un bouton de téléchargement de fichier caché. Cela donne encore plus de liberté dans le style que le style autorisé via style intégré de webkit[1].
L’étiquette a été créée dans le but exact de diriger tous les événements de clic correspondants vers les entrées enfants.[2]Par conséquent, vous n’avez plus besoin de JavaScript pour diriger l’événement click vers le bouton d’entrée. Vous devriez utiliser quelque chose comme ce qui suit:
label.myLabel input[type="file"] {
position:absolute;
top: -1000px;
}
/***** Example custom styling *****/
.myLabel {
border: 2px solid #AAA;
border-radius: 4px;
padding: 2px 5px;
margin: 2px;
background: #DDD;
display: inline-block;
}
.myLabel:hover {
background: #CCC;
}
.myLabel:active {
background: #CCF;
}
.myLabel :invalid + span {
color: #A44;
}
.myLabel :valid + span {
color: #4A4;
}
<label class="myLabel">
<input type="file" required/>
<span>My Label</span>
</label>
J'ai utilisé une position fixe pour masquer l'entrée, pour la faire fonctionner même dans les versions anciennes d'Internet Explorer (IE8 émulé - a refusé de travailler sur une entrée de fichier visibility:hidden
ou display:none
). J'ai testé dans IE7 imité et plus, et cela a fonctionné parfaitement.
<button>
s dans les balises <label>
malheureusement, vous devrez donc définir vous-même les styles pour les boutons. Pour moi, c'est le seul inconvénient de cette approche.for
est défini, sa valeur est utilisée pour déclencher l'entrée avec le même id
que l'attribut for
sur le <label>
.Veuillez trouver ci-dessous un moyen qui fonctionne sur tous les navigateurs. Fondamentalement, je mets l'entrée en haut de l'image. Je le fais énormément en utilisant font-size pour que l'utilisateur clique toujours sur le bouton de téléchargement.
.myFile {
position: relative;
overflow: hidden;
float: left;
clear: left;
}
.myFile input[type="file"] {
display: block;
position: absolute;
top: 0;
right: 0;
opacity: 0;
font-size: 100px;
filter: alpha(opacity=0);
cursor: pointer;
}
<label class="myFile">
<img src="http://wscont1.apps.Microsoft.com/winstore/1x/c37a9d99-6698-4339-acf3-c01daa75fb65/Icon.13385.png" alt="" />
<input type="file" />
</label>
Le meilleur exemple est celui-ci, No Hiding, No jQuery, il est complètement pur CSS
http://css-tricks.com/snippets/css/custom-file-input-styling-webkitblink/
.custom-file-input::-webkit-file-upload-button {
visibility: hidden;
}
.custom-file-input::before {
content: 'Select some files';
display: inline-block;
background: -webkit-linear-gradient(top, #f9f9f9, #e3e3e3);
border: 1px solid #999;
border-radius: 3px;
padding: 5px 8px;
outline: none;
white-space: nowrap;
-webkit-user-select: none;
cursor: pointer;
text-shadow: 1px 1px #fff;
font-weight: 700;
font-size: 10pt;
}
.custom-file-input:hover::before {
border-color: black;
}
.custom-file-input:active::before {
background: -webkit-linear-gradient(top, #e3e3e3, #f9f9f9);
}
<input type="file" class="custom-file-input">
Cela semble assez bien s’occuper des affaires. n fidde est ici:
<label for="upload-file">A proper input label</label>
<div class="upload-button">
<div class="upload-cover">
Upload text or whatevers
</div>
<!-- this is later in the source so it'll be "on top" -->
<input name="upload-file" type="file" />
</div> <!-- .upload-button -->
/* first things first - get your box-model straight*/
*, *:before, *:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
label {
/* just positioning */
float: left;
margin-bottom: .5em;
}
.upload-button {
/* key */
position: relative;
overflow: hidden;
/* just positioning */
float: left;
clear: left;
}
.upload-cover {
/* basically just style this however you want - the overlaying file upload should spread out and fill whatever you turn this into */
background-color: gray;
text-align: center;
padding: .5em 1em;
border-radius: 2em;
border: 5px solid rgba(0,0,0,.1);
cursor: pointer;
}
.upload-button input[type="file"] {
display: block;
position: absolute;
top: 0; left: 0;
margin-left: -75px; /* gets that button with no-pointer-cursor off to the left and out of the way */
width: 200%; /* over compensates for the above - I would use calc or sass math if not here*/
height: 100%;
opacity: .2; /* left this here so you could see. Make it 0 */
cursor: pointer;
border: 1px solid red;
}
.upload-button:hover .upload-cover {
background-color: #f06;
}
Tout moyen facile de couvrir TOUTES les entrées de fichier consiste à simplement styliser votre entrée [type = button] et à la placer globalement pour transformer les entrées de fichier en boutons:
$(document).ready(function() {
$("input[type=file]").each(function () {
var thisInput$ = $(this);
var newElement = $("<input type='button' value='Choose File' />");
newElement.click(function() {
thisInput$.click();
});
thisInput$.after(newElement);
thisInput$.hide();
});
});
Voici un exemple de bouton CSS que j'ai obtenu de http://cssdeck.com/labs/beautiful-flat-buttons :
input[type=button] {
position: relative;
vertical-align: top;
width: 100%;
height: 60px;
padding: 0;
font-size: 22px;
color:white;
text-align: center;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
background: #454545;
border: 0;
border-bottom: 2px solid #2f2e2e;
cursor: pointer;
-webkit-box-shadow: inset 0 -2px #2f2e2e;
box-shadow: inset 0 -2px #2f2e2e;
}
input[type=button]:active {
top: 1px;
outline: none;
-webkit-box-shadow: none;
box-shadow: none;
}
Je viens de rencontrer ce problème et ai écrit une solution pour ceux qui utilisent Angular. Vous pouvez écrire une directive personnalisée composée d'un conteneur, d'un bouton et d'un élément d'entrée avec un fichier type. Avec CSS, vous placez ensuite l'entrée sur le bouton personnalisé, mais avec l'opacité 0. Vous définissez la hauteur et la largeur du conteneur sur exactement la largeur et la hauteur du décalage du bouton et la hauteur et la largeur de l'entrée sur 100% du conteneur.
la directive
angular.module('myCoolApp')
.directive('fileButton', function () {
return {
templateUrl: 'components/directives/fileButton/fileButton.html',
restrict: 'E',
link: function (scope, element, attributes) {
var container = angular.element('.file-upload-container');
var button = angular.element('.file-upload-button');
container.css({
position: 'relative',
overflow: 'hidden',
width: button.offsetWidth,
height: button.offsetHeight
})
}
};
});
un modèle de jade si vous utilisez du jade
div(class="file-upload-container")
button(class="file-upload-button") +
input#file-upload(class="file-upload-input", type='file', onchange="doSomethingWhenFileIsSelected()")
le même modèle en HTML si vous utilisez HTML
<div class="file-upload-container">
<button class="file-upload-button"></button>
<input class="file-upload-input" id="file-upload" type="file" onchange="doSomethingWhenFileIsSelected()" />
</div>
le css
.file-upload-button {
margin-top: 40px;
padding: 30px;
border: 1px solid black;
height: 100px;
width: 100px;
background: transparent;
font-size: 66px;
padding-top: 0px;
border-radius: 5px;
border: 2px solid rgb(255, 228, 0);
color: rgb(255, 228, 0);
}
.file-upload-input {
position: absolute;
top: 0;
left: 0;
z-index: 2;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}