Erstellt am

Erstelle eine stylishe, barrierefreie Datei-Auswahl in 3 Schritten

Native HMTL-Elemente sind von Haus aus barrierefrei. Die meisten lassen sich auch beliebig mit CSS stylen – wie ich in meinem Artikel über Web-Formulare gezeigt habe. Das Element zur Datei-Auswahl zählt leider nicht dazu.

Das <input type="file"> Element wird vom Browser als Schaltfläche dargestellt, welche den Datei-Auswahldialog des Betriebssystems öffnet. Diese Schaltfläche lässt sich gar nicht mit CSS stylen – weder die Größe und Farbe noch die Schriftart. Aber, kein Grund zu verzweifeln! Ich zeige euch wie es geht.

Eine Person sucht in einer Aktentasche nach einem Dokument. Foto: © Anete Lusina / pexels.com

Schritt 1: Native HTML-Elemente verwenden

Wenn ich ein Web-Formular mit Datei-Auswahl baue, dann sollen alle Nutzer:innen Dateien auswählen und hochladen können. Dazu zählen auch Menschen, die auf Screenreader oder die Tastaturbedienung angewiesen sind. Aus diesem Grund verwende ich das native, barrierefreie <input type="file"> Element. Ich habe eine Demo mit dem React-Framework erstellt. So sieht mein JSX-Code aus:

<label htmlFor="filepicker" className={styles.filePicker}> <span>Upload PDF</span> <input id="filepicker" type="file" accept=".pdf" aria-describedby="selected-file" onChange={event => onFilePickerChange(event)} /> </label> <p id="selected-file" aria-hidden="true">{selectedFile}</p>

Ich verwende ein label Element, das die sichtbare Beschriftung meiner Datei-Auswahl ("Upload PDF") sowie das visuell verborgene input Element enthält. Auf diese Weise fungiert das label Element als sichtbare UI-Komponente, das sich beliebig stylen lässt (mehr dazu in Schritt 2).

Das p Element zeigt den Hinweis an, dass noch keine Datei ausgewählt wurde. Nach der Auswahl einer Datei zeigt es den Dateinamen (siehe Schritt 3). Ich setze das Attribut aria-hidden="true", um den Text selbst vor assistiven Technologien zu verbergen. Nun wird der Hinweistext nur dann vorgelesen, wenn Nutzer:innen mit der Datei-Auswahl interagieren, dank dem Attribut aria-describedby.

Schritt 2: Etwas CSS-Magie anwenden

Als nächstes mache ich das input Element mit CSS unsichtbar und positioniere es über dem label Element. Das erlaubt mir, die sichtbare Beschriftung benutzerdefiniert zu gestalten:

form label[for].filePicker { position: relative; background-color: rgb(49, 4, 92); color: white; font-size: 1rem; // ... more custom styling } form label[for].filePicker input[type=file] { position: absolute; top: 0; left: 0; height: 100%; width: 100%; opacity: 0; }

Achtet bitte darauf, das <input type="file"> Element nicht vor assistiven Technologien zu verbergen. Die Nutzung von display: none oder das Setzen einer Größe von null Pixel würde dazu führen, dass Screenreader das Element nicht mehr auffinden können.

Damit auch sehende Nutzer:innen ein visuelles Feedback erhalten, zeichne ich eine Outline für das label Element ein, wenn der Mauszeiger darüber bewegt wird oder wenn das darin verschachtelte input Element fokussiert wird.

form label[for].filePicker:focus-within, form label[for].filePicker:hover { outline: 2px solid black; outline-offset: 2px; }

Schritt 3: Eine Prise JavaScript

Als letzten Schritt möchte ich den Dateinamen anzeigen, wenn Nutzer:innen eine Datei ausgewählt haben. Zu diesem Zweck nutz ich das change Event, das ausgelöst wird, wenn der Eingabewert verändert wird.

const FileUpload: React.FunctionComponent = () => { const [selectedFile, setSelectedFile] = useState('No file selected'); const onFilePickerChange = (event: React.ChangeEvent<HTMLInputElement>) => { const files = Array.from(event.target.files ?? []); if (files.length > 0) { setSelectedFile(files[0].name); } } return ( // Only the relevant sections of the JSX code <input type="file" // ... onChange={event => onFilePickerChange(event)} /> <p id="selected-file" aria-hidden="true">{selectedFile}</p> // ... ); };

Natürlich könnt ihr das auch in reinem JavaScript umsetzen – oder irgendeinem Framework eurer Wahl. Ich liefere euch nur ein Beispiel für eine Implementierung als React-Komponente. Seht euch den kompletten Quellcode auf GitHub an.

Die perfekte Datei-Auswahl, oder?

Hier seht ihr meine gestylte Datei-Auswahl in Aktion. Probiert es aus! Zum Vergleich habe ich auch ein unverändertes <input type="file"> Element eingebaut.

Ich bin mit dem Resultat an sich sehr glücklich. Allerdings geht es immer besser. Die Datei-Auswahl lässt sich super mit der Tastatur bedienen. Leider gibt es Probleme bei der Kombination von gewissen Browsern und Screenreadern (siehe englische Version des Artikels).

Vielleicht werden diese Probleme durch zukünftige Updates gelöst. Oder ich finde noch eine bessere Lösung. Jedenfalls zeigt meine Demo, dass eine barrierefreie, gestylte Datei-Auswahl für Web-Formulare keine Hexerei ist.

Erstellt am

Impressum: Inhalte von Alexander Lehner, Wien/Österreich.