Accessible File Upload
Der Upload, der sagt, was er will
Ablagefläche, Entfernen-Symbol, Hinweis: drei Stellen, an denen Uploads verstummen.
Upload-Anatomie
Ein Dateifeld, drei verständliche Zustände
Sehen Sie, welche Texte vor, nach und bei einer fehlerhaften Auswahl gebraucht werden.
Konzeptdarstellung
Das Upload-Protokoll
Dies ist eine beschriftete Illustration, kein bedienbares Formular.
Kopierbare Grundlage
Markup und Zustände
accept hilft im Dateidialog. Der Server muss Typ, Inhalt und Größe trotzdem selbst prüfen.
<form action="/belege" method="post"
enctype="multipart/form-data">
<label for="beleg">Rechnungsbeleg</label>
<input id="beleg" name="beleg" type="file"
accept=".pdf,.jpg,.jpeg,.png"
aria-describedby="beleg-hinweis beleg-fehler">
<p id="beleg-hinweis">
PDF, JPG oder PNG. Höchstens 10 MB.
</p>
<p id="beleg-fehler" role="alert"></p>
<p id="beleg-status" role="status"></p>
<ul id="beleg-liste"></ul>
<button type="submit">Beleg senden</button>
</form>const feld = document.querySelector('#beleg');
const fehler = document.querySelector('#beleg-fehler');
const status = document.querySelector('#beleg-status');
const liste = document.querySelector('#beleg-liste');
const typen = ['application/pdf', 'image/jpeg', 'image/png'];
const maximum = 10 * 1024 * 1024;
feld.addEventListener('change', () => {
const datei = feld.files[0];
fehler.textContent = '';
status.textContent = '';
liste.replaceChildren();
feld.removeAttribute('aria-invalid');
if (!datei) return;
if (!typen.includes(datei.type) || datei.size > maximum) {
feld.setAttribute('aria-invalid', 'true');
feld.value = '';
fehler.textContent = 'Diese Datei ist nicht erlaubt. ' +
'Wählen Sie PDF, JPG oder PNG bis 10 MB.';
status.textContent = '';
return;
}
const eintrag = document.createElement('li');
const name = document.createElement('span');
const entfernen = document.createElement('button');
name.textContent = datei.name;
entfernen.type = 'button';
entfernen.textContent = datei.name + ' entfernen';
entfernen.addEventListener('click', () => {
feld.value = '';
liste.replaceChildren();
status.textContent = 'Datei entfernt.';
feld.focus();
});
eintrag.append(name, entfernen);
liste.append(eintrag);
status.textContent = '1 Datei ausgewählt.';
});So prüfen Sie es
- Tab ins Feld: Name und Formathinweis werden zusammen angesagt.
- Eine erlaubte Datei wählen: Die Statusmeldung nennt die Auswahl ohne Fokuswechsel.
- Eine zu große oder falsche Datei wählen: Der Fehler nennt Ursache und nächste Handlung.
- „Dateiname entfernen“ auslösen: Der Fokus steht danach wieder im Dateifeld.
Aus dem Prüfbericht
Drei Stellen, drei Befunde
Kritisch Die Ablagefläche hat keinen Namen Regel label
Das Dateifeld trägt nur einen gestrichelten Rahmen. Ein label mit for nennt, was hochgeladen werden soll.
Kritisch Das Entfernen-Symbol hat keinen Namen Regel button-name
Das × neben der Datei sagt nur „Schaltfläche“. aria-label nennt „Rechnung-2026.pdf entfernen“.
Kritisch aria-describedby trifft nichts Regel aria-valid-attr-value
Der Verweis nennt eine id, die es nicht gibt. Der Hinweis „PDF oder JPG, höchstens 10 MB“ bleibt ungehört.
Zum Mitnehmen
Der Upload, korrigiert
Ein label, ein Name, eine passende id. Die Ablagefläche bleibt.
Korrektur in 2 Schritten ansehen
Das Dateifeld benennen und den Hinweis anbinden
label nennt den Zweck, aria-describedby zeigt auf die id des Hinweises. Beide ids müssen übereinstimmen.
KorrekturvergleichSchritt 1 · HTML Vorher
<input type="file" name="beleg" aria-describedby="upload-hinweis"> <p id="hinweis-upload">PDF oder JPG, höchstens 10 MB</p>Nachher
<label for="beleg">Rechnung hochladen</label> <input id="beleg" type="file" name="beleg" aria-describedby="upload-hinweis"> <p id="upload-hinweis">PDF oder JPG, höchstens 10 MB</p>Markierte Zeilen wurden geändert
So prüfen Sie es Tab ins Feld. Ein Vorleseprogramm sagt „Rechnung hochladen“ und danach den Hinweis.
Dem Entfernen-Symbol einen Namen geben
Der Name nennt Aktion und Datei. So weiß man, was verschwindet, bevor man drückt.
KorrekturvergleichSchritt 2 · HTML Vorher
<button type="button" class="remove">×</button>Nachher
<button type="button" class="remove" aria-label="Rechnung-2026.pdf entfernen"> <span aria-hidden="true">×</span> </button>Markierte Zeilen wurden geändert
So prüfen Sie es Tab auf das ×. Ein Vorleseprogramm sagt „Rechnung-2026.pdf entfernen, Schaltfläche“.
