So erstellst du ein Formular in HTML
Ein Formular ist ein <form>-Element mit Feldern und einem Absende-Button. Jedes Feld braucht einen name: Das ist der Schlüssel, unter dem der Wert gesendet wird. Füll das Formular aus und drück auf Send. Die Vorschau schickt nichts irgendwohin; sie zeigt genau das an, was der Browser gesendet hätte.
Die Bestandteile:
actionist die URL, an die die Daten gehen, undmethodgibt an, wie (hierpost).namean jedem Feld. Sein Wert ist das, was der Leser eingetippt hat.<label>benennt jedes Feld auf dem Bildschirm und für Screenreader (siehe HTML Label).requiredundtype="email"lassen den Browser die Felder vor dem Senden prüfen. Versuch, mit leerem Namen oder mitabcals E-Mail zu senden.- Der Absende-Button schickt das Formular ab. Enter in einem Textfeld ebenfalls.
action und method: wohin und wie die Daten gehen
| Attribut | Werte | Standard |
|---|---|---|
action | Eine beliebige URL | Die URL der aktuellen Seite |
method | get, post, dialog | get |
enctype | application/x-www-form-urlencoded, multipart/form-data, text/plain | application/x-www-form-urlencoded |
Mit method="get" werden die Felder zum Query-String der URL: Ein Suchformular mit name="q" geht zu /search?q=blue+shoes. Das ist richtig für Suchen und Filter, weil man das Ergebnis als Lesezeichen speichern und teilen kann. Mit method="post" kommen die Felder in den Body der Anfrage und erscheinen weder in der Adressleiste noch im Verlauf. Nimm POST für alles, was anmeldet, erstellt, ändert oder löscht, und für Passwörter.
Ein Formular mit Datei-Upload (<input type="file">) braucht method="post" und enctype="multipart/form-data", sonst wird nur der Dateiname gesendet. method="dialog" ist für ein Formular in einem <dialog>: Beim Absenden schließt sich der Dialog, statt eine Anfrage zu schicken.
Was gesendet wird
Nur Felder mit name werden gesendet, und nur, wenn sie nicht disabled sind. Drück auf Submit und vergleiche die Felder mit dem, was das Formular sendet:
Das Formular sendet city, zip, source und action. Das Feld ohne Namen, das deaktivierte Feld und die nicht angehakte Checkbox fehlen. Versteckte Inputs werden gesendet, aber nie angezeigt, und der Absende-Button schickt seinen eigenen name und value mit, weil er der Button war, der benutzt wurde.
Felder mit fieldset und legend gruppieren
<fieldset> zeichnet einen Kasten um zusammengehörige Felder, und <legend> ist seine Beschriftung. Screenreader sagen die Legende an, wenn der Fokus in die Gruppe kommt, und genau das macht eine Reihe von Radio Buttons wie unten verständlich: „Delivery, Standard, Auswahlschalter“.
disabled an einem fieldset deaktiviert auf einen Schlag jedes Feld darin, und keines davon wird gesendet. Entferne es, und die Geschenkfelder werden benutzbar.
Eingebaute Validierung: required, pattern und Co.
Browser prüfen diese Attribute vor dem Absenden und zeigen beim ersten Feld, das durchfällt, eine Meldung:
| Attribut | Prüft |
|---|---|
required | Das Feld ist nicht leer (eine Checkbox ist angehakt) |
type="email", type="url" | Der Wert sieht wie eine E-Mail-Adresse oder URL aus |
minlength, maxlength | Textlänge |
min, max, step | Bereich von Zahlen und Datumswerten |
pattern | Der ganze Wert passt auf einen regulären Ausdruck |
:invalid und :valid stylen Felder nach ihrem Zustand. :user-invalid ist meistens besser: Es greift erst, nachdem der Leser das Feld geändert und verlassen oder versucht hat abzusenden, damit ein leeres Formular nicht gleich komplett rot aufgeht.
Drei Dinge an pattern bringen Leute ins Stolpern. Es muss auf den ganzen Wert passen (kein ^ oder $ nötig). Es greift nur, wenn das Feld nicht leer ist, kombiniere es also mit required. Und die Fehlermeldung des Browsers ist allgemein, beschreib das Format also in sichtbarem Text neben dem Feld. Chrome und Firefox hängen den Text aus title an ihre Meldung an, aber der wird leicht übersehen.
Um die Prüfungen abzuschalten, etwa während du die Validierung deines Servers testest, füg dem <form> novalidate hinzu. Ein einzelner Absende-Button kann sie mit formnovalidate überspringen.
Die Validierung im Browser dient der Bequemlichkeit des Lesers. Jeder kann die Seite bearbeiten oder eine Anfrage ohne sie schicken, der Server muss also jeden Wert erneut prüfen.
Eigene Meldungen mit setCustomValidity
Wenn sich eine Regel nicht als Attribut schreiben lässt, etwa „die beiden Passwörter müssen übereinstimmen“, setzt du die Meldung per JavaScript. Ein Feld mit einer nicht leeren eigenen Meldung ist ungültig; ein leerer String macht es wieder gültig:
Das Wiederholungsfeld hat keinen name, es wird also nur eine Kopie des Passworts gesendet.
Das Absenden per JavaScript verarbeiten
Um das Formular zu senden, ohne die Seite zu verlassen, hörst du auf submit, rufst preventDefault() auf und liest die Felder mit FormData. Auf submit statt auf das click eines Buttons zu hören, erfasst jede Art des Absendens, auch Enter, und läuft erst, nachdem die eingebaute Validierung bestanden ist:
Object.fromEntries(new FormData(form)) macht aus den Feldern ein einfaches Objekt. Für Felder, die mehrere Werte haben können (Checkboxen mit gemeinsamem Namen, ein Mehrfach-Select), nimm stattdessen formData.getAll('name'), weil das Objekt nur den letzten Wert behält.
Häufige Fehler
- Felder ohne
name. Sie fehlen ohne Meldung in den gesendeten Daten. - Platzhalter statt Labels. Der Hinweis verschwindet, sobald der Leser tippt. Nimm ein
<label>. - Ein
<button>ohnetype, das für etwas anderes als das Absenden gedacht ist. In einem Formular ist es ein Absende-Button. - Ein Formular in einem Formular. Verschachtelte Formulare sind ungültig; der Browser ignoriert das innere
<form>-Tag. - Auf
clickam Absende-Button hören statt aufsubmitam Formular. Absenden per Enter wird verpasst. - Sich auf dem Server auf die Browser-Validierung verlassen. Validiere dort erneut.
- GET für Passwörter. Sie landen in der URL, im Verlauf und in Server-Logs.
Häufig gestellte Fragen
Wie erstelle ich ein Formular in HTML?
Umschließ die Felder mit <form action="/signup" method="post">, gib jedem Feld einen name und ein <label> und beende es mit <button type="submit">. Beim Absenden schickt der Browser jedes Paar name=value an die URL in action.
Was ist der Unterschied zwischen GET und POST in einem Formular?
method="get" (der Standard) hängt die Felder an die URL, etwa /search?q=shoes, was zu Suchen und Filtern passt, die man als Lesezeichen speichern können soll. method="post" schickt sie im Body der Anfrage, und das willst du für Logins, Registrierungen und alles, was Daten ändert.
Warum wird mein Formularfeld nicht mitgesendet?
Es hat kein name-Attribut, oder es ist disabled. Nur Felder mit Namen, die aktiviert sind, werden gesendet. Eine nicht angehakte Checkbox oder ein nicht gewählter Radio Button fehlt ebenfalls komplett.
Wofür sind fieldset und legend da?
<fieldset> gruppiert zusammengehörige Felder, und <legend> ist die Beschriftung der Gruppe. Screenreader sagen die Legende an, wenn der Fokus in die Gruppe kommt, und genau das macht eine Gruppe von Radio Buttons verständlich. disabled an einem fieldset deaktiviert jedes Feld darin.
Wie validiere ich ein Formular in HTML ohne JavaScript?
Mit Attributen: required, type="email", minlength, maxlength, min, max und pattern. Der Browser blockiert das Absenden und zeigt eine Meldung beim ersten ungültigen Feld. Validiere immer auch auf dem Server, denn diese Prüfungen laufen im Browser des Lesers und lassen sich umgehen.
Wie verhindere ich, dass ein Formular die Seite neu lädt?
Hör auf das submit-Event des Formulars, ruf event.preventDefault() auf und schick die Daten selbst mit fetch: form.addEventListener('submit', (e) => { e.preventDefault(); fetch(form.action, { method: 'POST', body: new FormData(form) }); }).