web-dev-qa-db-fra.com

Styling d'un bouton de type d'entrée = "fichier"

Comment qualifiez-vous un bouton d'entrée type="file"?

647
Shivanand

Le style des entrées de fichier est notoirement difficile, car la plupart des navigateurs ne changeront pas l'apparence de CSS ni de javascript.

Même la taille de l'entrée ne répondra pas aux goûts de:

<input type="file" style="width:200px">

Au lieu de cela, vous devrez utiliser l'attribut size:

<input type="file" size="60" />

Pour tout style plus sophistiqué que celui-ci (par exemple, modification de l'apparence du bouton de navigation), vous devrez examiner l'approche délicate consistant à superposer un bouton et une zone de saisie de style au-dessus de l'entrée de fichier natif. L'article déjà mentionné par la rm à l'adresse www.quirksmode.org/dom/inputfile.html est le meilleur que j'ai vu.

196
Jonathan Moffatt

Vous n'avez pas besoin de JavaScript pour cela! Voici une solution multi-navigateur:

Voir cet exemple! - Cela fonctionne sous Chrome/FF/IE IE10/9/8/7)

La meilleure approche serait d’avoir un élément d’étiquette personnalisé avec un attribut for attaché à un élément d’entrée de fichier caché . (Pour que cela fonctionne, l'attribut for du libellé doit correspondre à id de l'élément de fichier.

<label for="file-upload" class="custom-file-upload">
    Custom Upload
</label>
<input id="file-upload" type="file"/>

En guise d'alternative, vous pouvez aussi simplement envelopper l'élément d'entrée du fichier avec une étiquette directement: --- ( (exemple)

<label class="custom-file-upload">
    <input type="file"/>
    Custom Upload
</label>

En termes de style, il suffit de cacher1 l'élément d'entrée utilisant le sélecteur d'attribut .

input[type="file"] {
    display: none;
}

Il vous suffit ensuite de styler l'élément personnalisé label. (exemple) .

.custom-file-upload {
    border: 1px solid #ccc;
    display: inline-block;
    padding: 6px 12px;
    cursor: pointer;
}

1 - Il est à noter que si vous masquez l'élément à l'aide de display: none, il ne fonctionnera pas dans IE8 et les versions antérieures. Sachez également que jQuery valide ne valide pas les champs cachés par défaut. Si l'une de ces choses vous pose problème, voici deux méthodes différentes pour masquer l'entrée ( 1 , - 2 ) qui fonctionne dans ces circonstances.

883
Josh Crozier

suivez ces étapes, vous pourrez alors créer des styles personnalisés pour votre formulaire de téléchargement de fichier:

  1. c'est le simple formulaire HTML (veuillez lire les commentaires HTML que j'ai écrits ci-dessous)

    <form action="#type your action here" method="POST" enctype="multipart/form-data">
      <div id="yourBtn" style="height: 50px; width: 100px;border: 1px dashed #BBB; cursor:pointer;" onclick="getFile()">Click to upload!</div>
      <!-- this is your file input tag, so i hide it!-->
      <div style='height: 0px;width:0px; overflow:hidden;'><input id="upfile" type="file" value="upload"/></div>
      <!-- here you can have file submit button or you can write a simple script to upload the file automatically-->
      <input type="submit" value='submit' >
    </form>
    
  2. utilisez ensuite ce simple script pour transmettre l’événement click à la balise d’entrée.

    function getFile(){
         document.getElementById("upfile").click();
    }
    

    Vous pouvez désormais utiliser n'importe quel style sans vous soucier de la modification des styles par défaut.

Je le sais très bien car j'essaie de changer les styles par défaut depuis un mois et demi. Croyez-moi, c'est très difficile, car différents navigateurs ont des balises d'entrée différentes. Utilisez donc celui-ci pour créer vos formulaires de téléchargement de fichiers personnalisés. Voici le code UPLOAD AUTOMATED complet.

function getFile() {
  document.getElementById("upfile").click();
}

function sub(obj) {
  var file = obj.value;
  var fileName = file.split("\\");
  document.getElementById("yourBtn").innerHTML = fileName[fileName.length - 1];
  document.myForm.submit();
  event.preventDefault();
}
#yourBtn {
  position: relative;
  top: 150px;
  font-family: calibri;
  width: 150px;
  padding: 10px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border: 1px dashed #BBB;
  text-align: center;
  background-color: #DDD;
  cursor: pointer;
}
<form action="#type your action here" method="POST" enctype="multipart/form-data" name="myForm">
  <div id="yourBtn" onclick="getFile()">click to upload a file</div>
  <!-- this is your file input tag, so i hide it!-->
  <!-- i used the onchange event to fire the form submission-->
  <div style='height: 0px;width: 0px; overflow:hidden;'><input id="upfile" type="file" value="upload" onchange="sub(this)" /></div>
  <!-- here you can have file submit button or you can write a simple script to upload the file automatically-->
  <!-- <input type="submit" value='submit' > -->
</form>
183
teshguru

Cachez-le avec css et utilisez un bouton personnalisé avec $ (sélecteur) .click () pour activer le bouton Parcourir. puis définissez un intervalle pour vérifier la valeur du type d'entrée du fichier. l'intervalle peut afficher la valeur pour l'utilisateur afin que celui-ci puisse voir ce qui est téléchargé. l'intervalle s'effacera lorsque le formulaire sera soumis [EDIT] Désolé, je suis très occupé. Je voulais mettre à jour ce message. Voici un exemple.

<form action="uploadScript.php" method="post" enctype="multipart/form-data">
<div>
    <!-- filename to display to the user -->
    <p id="file-name" class="margin-10 bold-10"></p>

    <!-- Hide this from the users view with css display:none; -->
    <input class="display-none" id="file-type" type="file" size="4" name="file"/>

    <!-- Style this button with type image or css whatever you wish -->
    <input id="browse-click" type="button" class="button" value="Browse for files"/>

    <!-- submit button -->
    <input type="submit" class="button" value="Change"/>
</div>
$(window).load(function () {
    var intervalFunc = function () {
        $('#file-name').html($('#file-type').val());
    };
    $('#browse-click').on('click', function () { // use .live() for older versions of jQuery
        $('#file-type').click();
        setInterval(intervalFunc, 1);
        return false;
    });
});
74
Ryan

HTML

<div class="new_Btn">SelectPicture</div><br>
<input id="html_btn" type='file'" /><br>

CSS

.new_Btn {
// your css propterties
}

#html_btn {
 display:none;
}

jQuery

$('.new_Btn').bind("click" , function () {
        $('#html_btn').click();
    });
//edit: 6/20/2014: Be sure to use ".on" not ".bind" for newer versions of jQuery

Violon : http://jsfiddle.net/M7BXC/

Vous pouvez aussi atteindre vos objectifs sans jQuery avec JavaScript.

Maintenant, le newBtn est lié au html_btn et vous pouvez styler votre nouveau btn comme vous le souhaitez: D

59
Wykk

Tous les moteurs de rendu génèrent automatiquement un bouton lorsqu'un <input type="file"> est créé. Historiquement, ce bouton était complètement non-styleable. Cependant, Trident et WebKit ont ajouté des points d'ancrage via des pseudo-éléments.

Trident

A partir de IE10, le bouton de saisie de fichier peut être stylé à l'aide du pseudo-élément ::-ms-browse. En règle générale, toutes les règles CSS que vous appliquez à un bouton standard peuvent être appliquées au pseudo-élément. Par exemple:

::-ms-browse {
  background: black;
  color: red;
  padding: 1em;
}
<input type="file">

Cela s’affiche comme suit dans IE10 sous Windows 8:

This displays as follows in IE10 on Windows 8:

WebKit

WebKit fournit un point d'ancrage pour son bouton d'entrée de fichier avec le pseudo-élément ::-webkit-file-upload-button. Encore une fois, pratiquement toutes les règles CSS peuvent être appliquées, c'est pourquoi l'exemple Trident fonctionnera également ici:

::-webkit-file-upload-button {
  background: black;
  color: red;
  padding: 1em;
}
<input type="file">

Cela s’affiche comme suit dans Chrome 26 sous OS X:

This displays as follows in Chrome 26 on OS X:

53
Anselm

Je suis capable de le faire avec CSS pur en utilisant le code ci-dessous. J'ai utilisé bootstrap et font-awesome.

<link href="https://cdnjs.cloudflare.com/ajax/libs/Twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />

<label class="btn btn-default btn-sm center-block btn-file">
  <i class="fa fa-upload fa-2x" aria-hidden="true"></i>
  <input type="file" style="display: none;">
</label>
22
Karthik

Si vous utilisez Bootstrap 3, cela a fonctionné pour moi:

Voir http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/

.btn-file {
  position: relative;
  overflow: hidden;
}
.btn-file input[type=file] {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 100%;
  min-height: 100%;
  font-size: 100px;
  text-align: right;
  filter: alpha(opacity=0);
  opacity: 0;
  outline: none;
  background: white;
  cursor: inherit;
  display: block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/Twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />

<span class="btn btn-primary btn-file">
    Browse...<input type="file">
</span>

Qui produit le bouton de saisie de fichier suivant:

Example button

Sérieusement, consultez http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/

22
JDawg
 <label>
    <input type="file" />
 </label>

Vous pouvez envelopper votre type d'entrée = "fichier" à l'intérieur d'une étiquette pour l'entrée. Style de l'étiquette comme vous le souhaitez et masquer l'entrée avec display: none;

20
JGuo

Exemple de travail ici avec support natif de glisser-déposer: https://jsfiddle.net/j40xvkb3/

Lors du style d'une entrée de fichier, , vous ne devez interrompre aucune des interactions natives fournies par l'entrée .

L'approche display: none interrompt la prise en charge native du glisser-déposer.

Pour ne rien casser, vous devez utiliser l'approche opacity: 0 pour l'entrée et la positionner à l'aide d'un modèle relatif/absolu dans un wrapper.

En utilisant cette technique, vous pouvez facilement styler une zone de clic/déposer pour l'utilisateur et ajouter une classe personnalisée en javascript sur l'événement dragenter pour mettre à jour les styles et donner à l'utilisateur un retour d'information lui indiquant qu'il peut supprimer un fichier.

HTML:

<label for="test">
  <div>Click or drop something here</div>
  <input type="file" id="test">
</label>

CSS:

input[type="file"] {
  position: absolute;
  left: 0;
  opacity: 0;
  top: 0;
  bottom: 0;
  width: 100%;
}

div {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ccc;
  border: 3px dotted #bebebe;
  border-radius: 10px;
}

label {
  display: inline-block;
  position: relative;
  height: 100px;
  width: 400px;
}

Voici un exemple de travail (avec JS supplémentaire pour gérer les événements dragover et les fichiers supprimés).

https://jsfiddle.net/j40xvkb3/

J'espère que cela a aidé!

19
kevcha

C'est simple avec jQuery. Donner un exemple de code de la suggestion de Ryan avec une légère modification.

HTML basique:

<div id="image_icon"></div>
<div id="filename"></div>
<input id="the_real_file_input" name="foobar" type="file">

Veillez à définir le style sur l'entrée lorsque vous êtes prêt: opacity: 0 Vous ne pouvez pas définir display: none car il doit être cliquable. Mais vous pouvez le positionner sous le "nouveau" bouton ou ranger quelque chose d'autre avec z-index si vous préférez.

Configurez quelques instants pour cliquer sur l’entrée réelle lorsque vous cliquez sur l’image.

$('#image_icon').click(function() {
    $('#the_real_file_input').click();
});

Maintenant, votre bouton fonctionne. Il suffit de couper et coller la valeur une fois modifiée.

$('input[type=file]').bind('change', function() {
    var str = "";
    str = $(this).val();
    $("#filename").text(str);
}).change();

Tah dah! Vous devrez peut-être analyser la valeur val () pour obtenir quelque chose de plus significatif, mais vous devriez être prêt.

11
TLK

VISIBILITÉ: PICK caché

Je choisis habituellement le truc visibility:hidden

c'est mon bouton stylé

<div id="uploadbutton" class="btn btn-success btn-block">Upload</div>

c'est le bouton type d'entrée = fichier. Notez la règle visibility:hidden

<input type="file" id="upload" style="visibility:hidden;">

c'est le bit JavaScript pour les coller ensemble. Ça marche

<script>
 $('#uploadbutton').click(function(){
    $('input[type=file]').click();
 });
 </script>
8
Gianluca Ghettini

Voici une solution qui ne dénomme pas vraiment l'élément <input type="file" /> mais utilise plutôt un élément <input type="file" /> par-dessus d'autres éléments (qui peuvent être stylisés). L'élément <input type="file" /> n'est pas vraiment visible, de sorte que l'illusion générale est celle d'un contrôle de téléchargement de fichier bien stylé.

Je suis tombé sur ce problème récemment et malgré la pléthore de réponses sur Stack Overflow, aucune solution ne semblait vraiment convenir. Au final, j'ai fini par personnaliser ceci afin d'avoir une solution simple et élégante.

J'ai également testé cela sur Firefox, IE (11, 10 et 9), Chrome et Opera, iPad et quelques appareils Android.

Voici le lien JSFiddle -> http://jsfiddle.net/umhva747/

$('input[type=file]').change(function(e) {
    $in = $(this);
    $in.next().html($in.val());
    
});

$('.uploadButton').click(function() {
    var fileName = $("#fileUpload").val();
    if (fileName) {
        alert(fileName + " can be uploaded.");
    }
    else {
        alert("Please select a file to upload");
    }
});
body {
    background-color:Black;
}

div.upload {
    background-color:#fff;
    border: 1px solid #ddd;
    border-radius:5px;
    display:inline-block;
    height: 30px;
    padding:3px 40px 3px 3px;
    position:relative;
    width: auto;
}

div.upload:hover {
    opacity:0.95;
}

div.upload input[type="file"] {
    display: input-block;
    width: 100%;
    height: 30px;
    opacity: 0;
    cursor:pointer;
    position:absolute;
    left:0;
}
.uploadButton {
    background-color: #425F9C;
    border: none;
    border-radius: 3px;
    color: #FFF;
    cursor:pointer;
    display: inline-block;
    height: 30px;
    margin-right:15px;
    width: auto;
    padding:0 20px;
    box-sizing: content-box;
}

.fileName {
    font-family: Arial;
    font-size:14px;
}

.upload + .uploadButton {
    height:38px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form action="" method="post" enctype="multipart/form-data">
    <div class="upload">
        <input type="button" class="uploadButton" value="Browse" />
        <input type="file" name="upload" accept="image/*" id="fileUpload" />
        <span class="fileName">Select file..</span>
    </div>
    <input type="button" class="uploadButton" value="Upload File" />
</form>

J'espère que cela t'aides!!!

8
Satwik Nadkarny

la seule façon dont je peux penser est de trouver le bouton avec javascript après qu'il soit rendu et de lui attribuer un style

vous pourriez aussi regarder cette écriture

7
roman m
<input type="file" name="media" style="display-none" onchange="document.media.submit()">

Je voudrais normalement utiliser du javascript simple pour personnaliser la balise de saisie du fichier. Un champ de saisie masqué, en cliquant sur le bouton, appelle javascript le champ masqué, solution simple sans css ou tas de jQuery.

<button id="file" onclick="$('#file').click()">Upload File</button>
7
user2086641

Ici, nous utilisons une étendue pour déclencher la saisie du fichier type et nous avons simplement personnalisé cette étendue , de sorte que nous pouvons ajouter n'importe quel style de cette manière.

Notez que nous utilisons une balise d'entrée avec l'option de visibilité: cachée et que nous la déclenchons dans la plage.

.attachFileSpan{
color:#2b6dad;
cursor:pointer;
}
.attachFileSpan:hover{
text-decoration: underline;
}
<h3> Customized input of type file </h3>
<input id="myInput" type="file" style="visibility:hidden"/>

        <span title="attach file" class="attachFileSpan" onclick="document.getElementById('myInput').click()">
        Attach file
        </span>

référence

5
Abdallah Okasha

Placez le bouton de téléchargement du fichier sur votre bouton ou élément Nice et masquez-le.

Très simple et fonctionnera sur n'importe quel navigateur

<div class="upload-wrap">
    <button type="button" class="Nice-button">upload_file</button>
    <input type="file" name="file" class="upload-btn">
</div>

Modes

.upload-wrap {
    position: relative;
}

.upload-btn {
    position: absolute;
    left: 0;
    opacity: 0;
}
5
Tigran Babajanyan

Peut-être beaucoup d'awnsers. Mais j'aime ça en CSS pur avec les boutons fa:

.divs {
    position: relative;
    display: inline-block;
    background-color: #fcc;
}

.inputs {
    position:absolute;
    left: 0px;
    height: 100%;
    width: 100%;
    opacity: 0;
    background: #00f;
    z-index:999;
}

.icons {
    position:relative;
}
<div class="divs">
<input type='file' id='image' class="inputs">
<i class="fa fa-image fa-2x icons"></i>
</div>

<div class="divs">
<input type='file' id='book' class="inputs">
<i class="fa fa-book fa-5x icons"></i>
</div>
<br><br><br>
<div class="divs">
<input type='file' id='data' class="inputs">
<i class="fa fa-id-card fa-3x icons"></i>
</div>





<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>

Violon: https://jsfiddle.net/zoutepopcorn/v2zkbpay/1/

4
Johan Hoeksma

NIQUEMENT CSS

Utilisez ceci très simple et FACILE

Html:

<label>Attach your screenshort</label>
                <input type="file" multiple class="choose">

Css:

.choose::-webkit-file-upload-button {
    color: white;
    display: inline-block;
    background: #1CB6E0;
    border: none;
    padding: 7px 15px;
    font-weight: 700;
    border-radius: 3px;
    white-space: nowrap;
    cursor: pointer;
    font-size: 10pt;
}
4
Balvant Ahir

Voici une solution, qui montre également le nom du fichier choisi: http://jsfiddle.net/raft9pg0/1/

HTML:

<label for="file-upload" class="custom-file-upload">Chose file</label>
<input id="file-upload" type="file"/>
File: <span id="file-upload-value">-</span>

JS:

$(function() {
    $("input:file[id=file-upload]").change(function() {
        $("#file-upload-value").html( $(this).val() );
    });
});

CSS:

input[type="file"] {
    display: none;
}

.custom-file-upload {
      background: #ddd;
      border: 1px solid #aaa;
      border-top: 1px solid #ccc;
      border-left: 1px solid #ccc;
      -moz-border-radius: 3px;
      -webkit-border-radius: 3px;
      border-radius: 3px;
      color: #444;
      display: inline-block;
      font-size: 11px;
      font-weight: bold;
      text-decoration: none;
      text-shadow: 0 1px rgba(255, 255, 255, .75);
      cursor: pointer;
      margin-bottom: 20px;
      line-height: normal;
      padding: 8px 10px; }
3
Caleb

C’est une bonne façon de le faire avec le téléchargement de fichiers matériel/angular. Vous pouvez faire la même chose avec un bouton bootstrap.

Remarque: J'ai utilisé <a> au lieu de <button>, cela permet aux événements de clic de se propager.

<label>
    <input type="file" (change)="setFile($event)" style="display:none" />

    <a mat-raised-button color="primary">
      <mat-icon>file_upload</mat-icon>
      Upload Document
    </a>

  </label>
3
robert king

Cette semaine, j’avais également besoin de personnaliser le bouton et d’afficher le nom du fichier sélectionné, donc après avoir lu certaines des réponses ci-dessus (Merci, BTW), j’ai eu l’implémentation suivante:

HTML:

<div class="browse">
<label id="uploadBtn" class="custom-file-upload">Choose file
<input type="file" name="fileInput" id="fileInput" accept=".yaml" ngf-select ngf-change="onFileSelect($files)" />
</label>
<span>{{fileName}}</span>
</div>

CSS

   input[type='file'] {
    color: #a1bbd5;
    display: none;

}

.custom-file-upload {
    border: 1px solid #a1bbd5;
    display: inline-block;
    padding: 2px 8px;
    cursor: pointer;
}

label{
    color: #a1bbd5;
    border-radius: 3px;
}

Javascript (angulaire)

app.controller('MainCtrl', function($scope) {

        $scope.fileName = 'No file chosen';

          $scope.onFileSelect = function ($files) {
          $scope.selectedFile = $files;
          $scope.fileName = $files[0].name;
    };
});

Fondamentalement, je travaille avec ng-file-upload lib, Angular-wise lie le nom du fichier à mon $ scope et lui donne la valeur initiale "Aucun fichier choisi", je lie également la fonction onFileSelect () à Ainsi, quand un fichier est sélectionné, je récupère le nom du fichier à l’aide de l’API ng-upload et l’attribue à $ scope.filename.

3
lironn

Ne vous laissez pas berner par les "excellentes" solutions CSS uniquement, qui sont en réalité très spécifiques à un navigateur, ou qui superposent le bouton stylé au-dessus du bouton réel, ou qui vous obligent à utiliser un <label> au lieu d'un <button>, ou tout autre type. JavaScript IS nécessaire pour qu'il fonctionne correctement. S'il vous plaît étudier comment gmail et DropZone le font si vous ne me croyez pas.

Créez un style de bouton normal à votre guise, puis appelez une simple fonction JS pour créer et lier un élément d’entrée masqué à votre bouton stylé.

<!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>

Notez que le code ci-dessus le lie à chaque fois que l'utilisateur choisit un fichier. Ceci est important car "onchange" n'est appelé que si l'utilisateur modifie le nom du fichier. Mais vous souhaiterez probablement obtenir le fichier à chaque fois que l'utilisateur le fournira.

3
personal_cloud

css peut faire beaucoup ici ... avec un peu de ruse ...

<div id='wrapper'>
  <input type='file' id='browse'>
</div>

#wrapper {
     width: 93px; /*play with this value */
     height: 28px; /*play with this value */
     background: url('browseBtn.png') 0 0 no-repeat;
     border:none;
     overflow:hidden;
}

#browse{
     margin-left:-145px; /*play with this value */
     opacity:0; /* set to .5 or something so you can better position it as an overlay then back to zero again after you're done */
     -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
     filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
}

:: reference :: http://site-o-matic.net/?viewpost=19

- abbaye

2
Abbey

J'ai trouvé une méthode très simple pour passer du bouton de fichier à une image. Vous étiquetez simplement une image et placez-la au-dessus du bouton de fichier.

<html>
<div id="File button">
    <div style="position:absolute;">
        <!--This is your labeled image-->
        <label for="fileButton"><img src="ImageURL"></label>
    </div>
    <div>
        <input type="file" id="fileButton"/>
    </div>
</div>
</html>

Lorsque vous cliquez sur l'image étiquetée, vous sélectionnez le bouton Fichier.

2
D-Inventor

La meilleure façon consiste à utiliser le pseudo-élément: after ou: before en tant qu'élément sur l'entrée de. Ensuite, appelez ce pseudo-élément à votre guise. Je vous recommande de faire un style général pour tous les fichiers d'entrée comme suit:

input {
  height: 0px;
  outline: none;
}

input[type="file"]:before {
  content: "Browse";
  background: #fff;
  width: 100%;
  height: 35px;
  display: block;
  text-align: left;
  position: relative;
  margin: 0;
  margin: 0 5px;
  left: -6px;
  border: 1px solid #e0e0e0;
  top: -1px;
  line-height: 35px;
  color: #b6b6b6;
  padding-left: 5px;
  display: block;
}
1
Despertaweb

Voici une solution simple en CSS, qui crée une zone cible cohérente et vous permet de styler vos faux éléments comme vous le souhaitez.

L'idée de base est la suivante:

  1. Avoir deux "faux" éléments (une entrée de texte/un lien) en tant que frères et soeurs dans votre entrée de fichier réel. Absolument les positionner afin qu'ils soient exactement au-dessus de votre zone cible.
  2. Enveloppez votre entrée de fichier avec un div. Définissez overflow sur hidden (pour que le fichier ne déborde pas) et définissez-le exactement à la taille souhaitée pour votre zone cible.
  3. Définissez l'opacité sur 0 sur l'entrée de fichier afin qu'il soit masqué mais toujours cliquable. Donnez-lui une grande taille de police pour pouvoir cliquer sur toutes les parties de la zone cible.

Voici le jsfiddle: http://jsfiddle.net/gwwar/nFLKU/

<form>
    <input id="faux" type="text" placeholder="Upload a file from your computer" />
    <a href="#" id="browse">Browse </a>
    <div id="wrapper">
        <input id="input" size="100" type="file" />
    </div>
</form>
1
Kerry Liu

Une solution très intelligente utilisant jQuery qui fonctionne dans tous les navigateurs anciens ainsi que dans les nouveaux, j'ai trouvé ici . Il prend en charge tous les problèmes de style et click (), en utilisant le bouton de navigation du fichier. J'ai créé une version javascript simple: fiddle La solution est aussi simple que le génie: faites en sorte que l'entrée de fichier soit invisible et utilisez un morceau de code pour la placer sous le curseur de souris.

<div class="inp_field_12" onmousemove="file_ho(event,this,1)"><span>browse</span>
<input id="file_1" name="file_1" type="file" value="" onchange="file_ch(1)">
</div>
<div id="result_1" class="result"></div>


function file_ho(e, o, a) {
    e = window.event || e;
    var x = 0,
    y = 0;
    if (o.offsetParent) {
        do {
        x += o.offsetLeft;
        y += o.offsetTop;
        } while (o = o.offsetParent);
    }
var x1 = e.clientX || window.event.clientX;
var y1 = e.clientY || window.event.clientY;
var le = 100 - (x1 - x);
var to = 10 - (y1 - y);
document.getElementById('file_' + a).style.marginRight = le + 'px';
document.getElementById('file_' + a).style.marginTop = -to + 'px';
}

.inp_field_12 {
position:relative;
overflow:hidden;
float: left;
width: 130px;
height: 30px;
background: orange;
}
.inp_field_12 span {
position: absolute;
width: 130px;
font-family:'Calibri', 'Trebuchet MS', sans-serif;
font-size:17px;
line-height:27px;
text-align:center;
color:#555;
}
.inp_field_12 input[type='file'] {
cursor:pointer;
cursor:hand;
position: absolute;
top: 0px;
right: 0px;
-moz-opacity:0;
filter:alpha(opacity: 0);
opacity: 0;
outline: none;
outline-style:none;
outline-width:0;
ie-dummy: expression(this.hideFocus=true);
}
.inp_field_12:hover {
background-position:-140px -35px;
}
.inp_field_12:hover span {
color:#fff;
}
1
Michel

Ces réponses sont bien, et elles fonctionnent toutes pour des cas d'utilisation très spécifiques. C'est-à-dire qu'ils ont une opinion.

Donc, voici une réponse qui ne suppose rien, mais qui fonctionnera quelle que soit la façon dont vous la modifiez. Vous pouvez changer de design avec css, ajouter du javascript pour peut-être afficher un nom de fichier lors du changement, etc. cela fonctionnera toujours.

Code:

Voici le css de base

.file-input{
  pointer-events: none;
  position: relative;
  overflow: hidden;
}
.file-input > * {
  pointer-events: none;
}
.file-input > input[type="file"]{
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  opacity: 0;
  pointer-events: all;
  cursor: pointer;
  height: 100%;
  width: 100%;
}

et le noyau html:

<div class="file-input">
  <input type="file"/>
</div>

Comme vous pouvez le constater, nous forçons tout événement de pointeur (clic) se produisant sur l’élément .file-input, ou l’un de ses enfants, à être proxy vers l’entrée de fichier. En effet, l'entrée de fichier est positionnée de manière absolue et consommera toujours la largeur/hauteur du conteneur. Vous pouvez donc personnaliser pour répondre à vos besoins. stylisez le wrapper en un bouton, utilisez un js pour afficher le nom du fichier sur select, etc. rien ne se cassera tant que le code principal ci-dessus reste intact.

Comme vous le verrez dans la démo, j'ai ajouté un span avec le texte "Sélectionner un fichier" et une classe avec des styles supplémentaires pour styler le .file-input div. Cela devrait être le point de départ canonique de toute personne souhaitant créer un élément de téléchargement de fichier personnalisé.

Démo: JSFIDDLE

1
r3wt

Comme JGuo et CorySimmons , vous pouvez utiliser le comportement cliquable d'une étiquette pouvant être stylée, en masquant l'élément d'entrée du fichier le moins flexible.

<!DOCTYPE html>
<html>
<head>
<title>Custom file input</title>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
</head>

<body>

<label for="upload-file" class="btn btn-info"> Choose file... </label>
<input id="upload-file" type="file" style="display: none"
onchange="this.nextElementSibling.textContent = this.previousElementSibling.title = this.files[0].name">
<div></div>

</body>
</html>
1
KitKat

Si vous recherchez une bibliothèque javascript - solution prête à l'emploi, jquery-fileinput fonctionne très bien.

1
ellimilial

Mettre à jour Peu importe, cela ne fonctionne pas dans IE ou son nouveau frère, FF. Fonctionne sur tous les autres types d'élément comme prévu, mais ne fonctionne pas sur les entrées de fichier. Pour ce faire, une meilleure solution consiste simplement à créer une entrée de fichier et une étiquette associée. Faites en sorte que le fichier en entrée n’affiche pas et bouge, cela fonctionne de manière transparente dans IE9 +.

Attention: tout ce qui est en dessous c'est de la merde!

En utilisant des pseudo-éléments positionnés/dimensionnés par rapport à leur conteneur, nous pouvons nous en tirer avec un seul fichier d’entrée (aucun balisage supplémentaire n’est nécessaire) et un style comme à l’habitude.

démo

<input type="file" class="foo">

.foo {
    display: block;
    position: relative;
    width: 300px;
    margin: auto;
    cursor: pointer;
    border: 0;
    height: 60px;
    border-radius: 5px;
    outline: 0;
}
.foo:hover:after {
    background: #5978f8;
}
.foo:after {
    transition: 200ms all ease;
    border-bottom: 3px solid rgba(0,0,0,.2);
    background: #3c5ff4;
    text-shadow: 0 2px 0 rgba(0,0,0,.2);
    color: #fff;
    font-size: 20px;
    text-align: center;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: block;
    content: 'Upload Something';
    line-height: 60px;
    border-radius: 5px;
}

Appréciez les gars!

Ancienne mise à jour

Tourné cela dans un mixin Stylus. Devrait être assez facile pour l'un de vous, chats SCSS cool, pour le convertir.

file-button(button_width = 150px)
  display block
  position relative
  margin auto
  cursor pointer
  border 0
  height 0
  width 0
  outline none
  &:after
    position absolute
    top 0
    text-align center
    display block
    width button_width
    left -(button_width / 2)

Usage:

<input type="file">

input[type="file"]
    file-button(200px)
1
corysimmons

Une méthode simple et rapide consiste à définir le libellé en tant que bouton et à définir la position sur absolue afin qu'il flotte par-dessus le bouton d'origine. Vous voyez toujours le nom du fichier. Je pense cependant à une solution mobile.

0
Tomas Crofty

Simulez simplement un clic sur le <input> en utilisant la fonction trigger() lorsque vous cliquez sur un <div> stylé _. J'ai créé mon propre bouton à partir d'un <div>, puis j'ai déclenché un clic sur la input lorsque j'ai cliqué sur mon <div>. Cela vous permet de créer votre bouton comme bon vous semble car il s’agit d’un <div> et simule un clic sur votre fichier <input>. Ensuite, utilisez display: none sur votre <input>.

// div styled as my load file button
<div id="simClick">Load from backup</div>

<input type="file" id="readFile" />

// Click function for input
$("#readFile").click(function() {
    readFile();
});

// Simulate click on the input when clicking div
$("#simClick").click(function() {
    $("#readFile").trigger("click");
});
0
James Marquez

J'ai trouvé cette approche la plus simple et la plus légère.

Voici l'exemple de travail: http://codepen.io/c3zar22/pen/QNoYXN

Ci-dessous les explications:

  • ce serait le balisage:

    <label for="attach-project-file">
        <span id="remove-project-file" class="close">x</span>
        <div class="filename" id="attached-project-file">Click to select a file</div>
    </label>
    <input id="attach-project-file" type="file">
    
  • masquez l'entrée de manière hacky comme ceci:

    #attach-project-file {
        width: 0.1px;
        height: 0.1px;
        opacity: 0;
        overflow: hidden;
        position: absolute;
        z-index: -1;
    }
    
  • style à la place l'étiquette correspondante

    [for="attach-project-file"] {
        /* your styles here */
    }
    
  • bouton de style "supprimer le fichier"

    .close {
        font-size: 16px;
        padding: 10px;
        position: absolute;
        top: 0;
        right: 0;
        cursor: pointer;
        font-style: normal;
    }
    
  • L'élément .filename sera utilisé pour afficher le fichier sélectionné

  • voici le code JS commenté nécessaire (à l'aide de jQuery) pour le faire fonctionner:

    var $attach = $('#attach-project-file'),
        $remove = $('#remove-project-file'),
        $name = $('#attached-project-file');
    
    // initially hide the remove button
    $remove.hide();
    
    // do this when file input has changed
    // i.e.: a file has been selected
    $attach.on('change', function() {
        var val = $(this).val();
        if (val !== '') {
            // if value different than empty
    
            // show the file name as text
            // hide/text/fadeIn creates a Nice effect when changing the text
            $name
                .hide()
                .text(val)
                .fadeIn();
    
            // show the remove button
            $remove.fadeIn();
        } else {
            // if value empty, means the file has been removed
    
            // show the default text
            $name
                .hide()
                .text('Click to select a file')
                .fadeIn();
    
            // hide remove button
            $remove.fadeOut();
        }
    });
    
    // remove selected file when clicking the remove button
    // prevent click bubbling to the parent label and triggering file selection
    $remove.on('click', function(e) {
        e.preventDefault();
        e.stopPropagation();
    
        $attach
            .val('')
            .change(); // trigger change event
    });
    
0
Cezar D.

Si quelqu'un veut encore faire cela sans JavaScript, laissez-moi répondre à Josh:

Comment afficher le texte du nom du fichier:

La méthode la plus simple consiste à définir les deux éléments sur une position: relative, à attribuer un indice z supérieur à l'étiquette et à laisser une marge négative au fichier d'entrée jusqu'à ce que le texte de l'étiquette se trouve à l'endroit souhaité. Ne pas utiliser display: aucun sur l'entrée!

Exemple :

input[type="file"] {
  position:relative;
  z-index:1;
  margin-left:-90px;
}

.custom-file-upload {
  border: 1px solid #ccc;
  display: inline-block;
  padding: 6px 12px;
  cursor: pointer;
  position:relative;
  z-index:2;
  background:white;

}
0
KoU_warch

Voici une méthode compatible croisée qui fonctionnera dans Chrome, Firefox, Safari et IE.

$(window).on('resize',function() {
        var eqw = $('input[type=text]').width();
        $('textarea').width(eqw - 32);
        $('.fileoutline').width(eqw);
}).trigger('resize');

$('.file+.file').hide();

$(".file").click(function() {
    var input = $(this).next().find('input');
    input.click();
});
$("input[id='file1']").change(function () {
        $('.file+.file').show();
        var filename = $(this).val();
        $('.filename1').html(filename);
        $('.file').find('span').html('CHANGE FILE');
});
$("input[id='file2']").change(function() {
        var filename = $(this).val();
        $('.filename2').html(filename);
        $('.file').find('span').html('CHANGE FILE');
});
        
form { width:55%;margin:0 auto;padding-left:3vw;text-align:left; }
fieldset{border:0;margin:0;padding:0;}
textarea{overflow: auto;height:25vh;resize:none;outline:none;width:93%;background:none;padding:8px 15px;display:block;text-align:left;border:1px solid #000;margin:0;color:#000;font:700 0.85em/2.2 'Futura Book',Arial,sans-serif;}
input:focus{outline:none;}
input[type=text]{font-weight:700;font-size:0.85em;line-height:2.2;background:none;text-align:left;letter-spacing:0.02em;height:33px;display:block;width:100%;border:none;border-bottom:1px solid #000;margin:0 0 28px;color:#000;}
input:focus{outline:0;}
.fileoutline { width:100%;margin:25px auto 0px;left:0;right:0;height:40px;border:1px solid #000;position:relative; }
input[type=file] { -webkit-appearance: none;-moz-appearance:none;appearance: none;opacity:0;position:relative;width:100%;height:35px;font-weight:700;font-size:0.5em;line-height:28px;letter-spacing:0.2em;position: absolute;left: 0;top: 0;height: 100%;z-index:10; }
.file,.filename1,.filename2,#submit { font-size:10px;letter-spacing:0.02em;text-transform:uppercase;color:#ffffff;text-align:center;width:35%;}
.file,.filename1,.filename2 { font-weight:200;line-height:28px;}
.filename1,.filename2 { width:375px;overflow:hidden;top:0;text-align:right;position:absolute;display:block;height:26px;color:#000;}
.file { position:absolute;width:100px;top:6px;left:10px;background:#000;border-radius:14px; }
::-webkit-file-upload-button,::-ms-browse { width: 100%;height:25px;opacity: 0;-webkit-appearance: none;appearance: none; }
#submit{border:none;height:32px;background: #000;box-shadow:0 0 0 0.5px #fff,0 0 0 5px #000;margin:35px 0;float:right;display:block;}
<form action="" method="post" enctype="multipart/form-data">
    <input type="text" name="email" id="email" placeholder="Email address" />
    <input type="text"  type="text" name="name" id="title" placeholder="Name" />
    <textarea rows="7" cols="40" name="description" id="description" placeholder="Description"></textarea>
    <div class="fileoutline"><div class="file"><span>CHOOSE FILE</span><input type="file" name="file[]" id="file1"><div class="filename1">NO CHOSEN FILE</div></div></div>
    <div class="fileoutline"><div class="file"><span>CHOOSE FILE</span><input type="file" name="file[]" id="file2"><div class="filename2">NO CHOSEN FILE</div></div></div>
    <input type="submit" name="submit" value="Submit" id="submit">
</form>
0
davidcondrey

jquery version du script teshguru pour détecter automatiquement les entrées et les styles

<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<style>
#yourBtn{
   position: relative;
       top: 150px;
   font-family: calibri;
   width: 150px;
   padding: 10px;
   -webkit-border-radius: 5px;
   -moz-border-radius: 5px;
   border: 1px dashed #BBB; 
   text-align: center;
   background-color: #DDD;
   cursor:pointer;
  }
</style>
<script type="text/javascript">
$(document).ready(function()
{
    $('input[type=file]').each(function()
    {
        $(this).attr('onchange',"sub(this)");
        $('<div id="yourBtn" onclick="getFile()">click to upload a file</div>').insertBefore(this);
        $(this).wrapAll('<div style="height: 0px;width: 0px; overflow:hidden;"></div>');
    });
});
 function getFile(){
   $('input[type=file]').click();
 }
 function sub(obj){
    var file = obj.value;
    var fileName = file.split("\\");
    document.getElementById("yourBtn").innerHTML = fileName[fileName.length-1];
 }
</script>
</head>
<body>
<?php 
    var_dump($_FILES);
?>
<center>
<form action="" method="post" enctype="multipart/form-data" name="myForm">

<input id="upfile" name="file" type="file" value="upload"/>
<input type="submit" value='submit' >
</form>
</center>
</body>
</html>
0
h0mayun

Les solutions de plug-in que j'ai trouvées étaient trop lourdes, j'ai donc créé mon propre plug-in jQuery appelé Drolex FileStyle.

Ce plug-in vous permet de styler les champs de saisie de fichier comme vous le souhaitez. En fait, vous donnez à vos éléments div un style ressemblant à une entrée de fichier piégée et l’entrée de fichier réelle est automatiquement superposée avec une opacité de 0%. Aucun code HTML supplémentaire n'est requis. Incluez simplement les fichiers css et js dans la page de votre choix pour Drolex FileStyle et c'est tout! Editez le fichier css à votre convenance. N'oubliez pas la bibliothèque jQuery si votre page ne l'a pas déjà. Si le client n'exécute pas JavaScript, l'entrée du fichier ne sera pas modifiée par js ou css.

Testé pour fonctionner dans Chrome 24, Firefox 18, Internet Explorer 9. Devrait fonctionner dans les versions précédentes de celles-ci et d’autres.

Téléchargement: http://web.drolex.net/Drolex-FileStyle.Zip

0
drolex