Lerne Coding
Wie du Datei-Uploads stylen kannst! 💾
10.10.2019

Ein HTML-Datei Upload-Input-Element stylen

Inhaltsverzeichnis
[[TABLE OF CONTENTS]]

In diesem Artikel beschreibe ich euch, wie ihr einen File Upload Input erstellt und diesen stylen könnt. Das ist etwas kniffliger als normale Inputs, weil dort kaum Parameter standardmäßig verfügbar sind. Beim Stylen von File Uploads müssen wir JavaScript verwenden - aber keine Angst! Unten findet ihr auch einen fertigen JavaScript-Teil zum Kopieren.

Es gibt natürlich auch fertige Frameworks für CSS-Styling, zum Beispiel die folgenden:

Solche CSS-Frameworks haben natürlich oft einen großen Nachteil; sie sind überladen mit Zeug, das man eigentlich gar nicht benötigt. Deshalb zeige ich dir wie du einen Form-Upload stylen kannst. Der Standard-Input sieht nämlich in den meisten Internetbrowsern einfach grottig aus.

So sieht es dann zum Beispiel im Chrome standardmäßig aus; aber das können wir besser! In diesem Artikel zeige ich dir wie.

Datei Style Default
Datei Style Default

File-Uploads eignen sich zum Beispiel für:

  • PDF-Bewerbungen / -Lebenslauf
  • Bilder, um ein Produkt zum Verkauf zu beschreiben.
  • Viele andere großartige Dinge, die du damit machen willst.

Falls ihr nicht weiter wisst und noch Fragen zum Radio- oder Checkboxen-Stylen habt, kann ich auf den folgenden Artikel verweisen:

Checkboxen und Radio-Buttons ohne Javascript stylen

Der HTML Aufbau

Der HTML Aufbau für die Seite ist einfach gehalten. Das Wichtigste ist, dass das Attribut "enctype="multipart/form-data" gesetzt wird, damit keine Zeichenkodierung stattfindet. Das ist notwendig, um das Formular später korrekt und einfach ohne Decodierung auswerten zu können und die Datei zu speichern. Die Methode muss auf POST stehen, da sonst ein Dateiupload nicht funktionieren kann. Grundsätzlich ist es zu empfehlen, immer POST bei Formularen zu verwenden, bei denen Daten (ausgenommen Suchanfragen) übermittelt werden sollen. Da der GET Parameter in der URL Übertragen wird ist die TLS-Verschlüsselung unwirksam, da diese die Parameter nicht erfassst. Das sieht zum Beispiel so aus:

https://hellocoding.de/search?q=javascript

Suchanfragen & Filter sollten allerdings GET verwenden, damit der Link weiter an andere Leute gesendet werden kann. Wahlweise kann das Input Field mit dem type="file" ein multiple Attribute bekommen. Damit können gleich mehrere Dateien hochgeladen werden. Zu beachten ist, dass das Name Attribute in diesem Fall eckige Klammern [] am Ende benötigt! Das steht für einen Array, was bedeutet, dass in diesem Parameter eine Liste von Dateien stehen kann.

<form enctype="multipart/form-data" action="{Pfade Angabe zur Aktion}" method="POST">

    <input type="file" multiple name="Datein[]" id="files"> 
    <label for="files">Datei/n Hochladen</label>

    <button>Senden</button>
</form>

Das for Attribute muss den gleichen Inhalt haben wie die ID des Inputs, sodass diese beiden Elemente miteinander verknüpft sind.

Das CSS für den File Upload

Bei dem CSS ist zu beachten, dass das Input Feld rein theoretisch ausgeblendet werden muss, was aber leider gar nicht möglich ist. Heißt: "display: none" funktioniert nicht wie bei Checkboxen, wo man die Checkbox einfach auf Display none setzen und das Label dann stylen kann.

Mehr dazu findest du hier: Checkboxen und Radio-Buttons ohne Javascript stylen

Wir müssen das Display also komplett unsichtbar machen, ohne “display: none;” zu verwenden. Das sieht folgendermaßen aus.

input[type="file"]{
    opacity: 0;
    z-index: -1;
    position: absolute;
    top: -1px;
    left: 0;
    width: 0.1px;
    height: 0.1px;
}

Das Opacity Attribute alleine reicht dafür leider nicht aus, da dieses das Element nur unsichtbar macht, es aber seine Position behält und die Interaktion immer noch möglich ist.

Mittels user-select:none; kann der Nutzer auf keinen Fall mehr das Input-Feld anklicken. In seltenen Fällen könnte das so sonst noch passieren, wenne es auch sehr unwahrscheinlich ist.

Als nächstes müssen wir daher nun den Fokus vom Input auf das Label übertragen, sodass der Fokus entsprechend auf dem Label simuliert werden kann.

input[type="file"]:focus + label[for="files"]{
    border: 1px solid #85E5FF;
}

Hierfür benutzen wir den + Selector, womit wir über das Input die danach stehenden Elemente stylen können. In der Gestaltung des Fokus seid ihr vollkommen frei. Ihr könnt dort also komplett kreativ werden!

Falls du dich fragst wie das mit den eckigen Klammern genau funktioniert, schau doch mal in den Artikel über Interne und Externe Links zu Stylen. Dort beschriebe ich die eckige-Klammern-Selektoren ganz genau.

Bei dem Label des Files seid ihr ebenfalls komplett frei. Das ist eure eigentliche Interaktionsfläche für den Nutzer. Sie sollte für diesen ansprechend gestaltet sein.

Hier einmal ein CSS für die beispielhafte Gestaltung des Labels:

label[for="files"]{
    background: #FF7B47;
    padding: 10px;
    color: #fff;
    font-family: sans-serif;
    border-radius: 4px;
    cursor: pointer;
    font-size: 16px;
}

label[for="files"]:hover{
    background: #FF9E59;
}

Die Javascript-Funktion für den File Upload

Was das Design angeht, sind wir nun fertig. Allerdings werdet ihr jetzt feststellen müssen, dass der Nutzer kein Feedback bekommt, ob seine Datei oder Dateien korrekt ausgewählt worden sind. Darum kümmern wir uns also nun.

Wir prüfen dazu, bei einer Änderung des Input-Feldes, die Werte files.length und files. Wenn der Wert length größer 1 ist, wird die Anzahl und der Text "Dateien ausgewählt" angezeigt. Bei einem einzelnen File wird der Name der Datei und "Datei ausgewählt" angezeigt.

Ihr benötigt nur die Funktion und könnt diese dann in euren Document Ready oder am Ende eures HTML Files einbinden und aufrufen. Alternativ könnt ihr das untenstehende JavaScript in eine Datei, und somit komplett einbinden. Dieses ist direkt lauffähig mit dem oben stehenden HTML-Markup. Der Text für einzelne Uploads und Mehrfach-Uploads kann selber angepasst werden, je nach Sprache bzw. nach benötigten Bedürfnissen.

Unten findet ihr nochmal ein voll funktionsfähiges Beispiel.

/**
 * Upload File Helper for Styling
 * @author Felix Schürmeyer
 */

/* Aufruf der Funktion */

document.addEventListener("DOMContentLoaded", function(event) { 

    let single = "Datei Ausgewählt";
    let multiple = "Datein Ausgewält";

    fileUploadStyling(single,multiple);

})

/* Die Funktion */

function fileUploadStyling(single,multiple){
    let input = document.querySelectorAll("input[type=file]");
    for (let i = 0; i < input.length; i++) {
        var inputFile = input[i];
        inputFile.addEventListener('change',function(e){

            var label = this.nextElementSibling;

            if(this.files && this.files.length > 1){
                label.innerHTML = this.files.length + ' ' + multiple;
            }else{
                label.innerHTML = this.files[0].name + ' ' + single;
            }
        });
    }
}
input[type="file"]{
    opacity: 0;
    z-index: -1;
    position: absolute;
    top: -1px;
    left: 0;
    width: 0.1px;
    height: 0.1px;
    user-select: none;
}

input[type="file"]:focus + label[for="files"]{
    border: 1px solid #85E5FF;
}

label[for="files"]{
    background: #FF7B47;
    padding: 10px;
    color: #fff;
    font-family: sans-serif;
    border-radius: 4px;
    cursor: pointer;
    font-size: 16px;
}

label[for="files"]:hover{
    background: #FF9E59;
}
<form enctype="multipart/form-data" action="" method="POST">
		
    <input type="file" multiple name="Datein[]" id="files"> 
    <label for="files">Datei/n Hochladen</label>

    <button>Senden</button>
</form>
/**
 * Upload File Helper for Styling
 * @author Felix Schürmeyer
 */

/* Aufruf der Funktion */

document.addEventListener("DOMContentLoaded", function(event) { 

    let single = "Datei Ausgewählt";
    let multiple = "Datein Ausgewält";

    fileUploadStyling(single,multiple);

})

/* Die Funktion */

function fileUploadStyling(single,multiple){
    let input = document.querySelectorAll("input[type=file]");
    for (let i = 0; i < input.length; i++) {
        var inputFile = input[i];
        inputFile.addEventListener('change',function(e){

            var label = this.nextElementSibling;

            if(this.files && this.files.length > 1){
                label.innerHTML = this.files.length + ' ' + multiple;
            }else{
                label.innerHTML = this.files[0].name + ' ' + single;
            }
        });
    }
}

Schluss

Hier seht ihr nochmal ein voll funktionsfähiges Beispiel. Bei Fragen hinterlasst gerne einen Kommentar. Durch diese Anleitung könnt nun auch ihr ganz einfach einen Datei-Upload stylen!

Kommentare zum Artikel

Es sind noch keine Kommentare vorhanden? Sei der/die Erste und verfasse einen Kommentar zum Artikel "Wie du Datei-Uploads stylen kannst! 💾"!

Kommentar schreiben

Verwante Beiträge
close