Abschnitt 14 · Lektion 5
Das Kontaktformular
Das Formular ist das letzte große Stück des Portfolios, nur die Fußzeile fehlt dann noch bis Abschnitt 16. Neue Eigenschaften gibt es keine. Dafür treffen sich hier fünf Abschnitte auf einmal, nämlich das Raster aus Abschnitt 10, die Breakpoints aus 12, die Flexbox aus 9, die Zustände aus 14.2 und die Tokens aus 5.5.
Das Label gehört über das Feld
<p class="etikett">daneben</p>
<div class="feld feld--daneben">
<label for="a">Deine E-Mail-Adresse</label>
<input type="email" id="a">
</div>
<p class="etikett">darüber</p>
<div class="feld feld--drueber">
<label for="b">Deine E-Mail-Adresse</label>
<input type="email" id="b">
</div>
<p class="hinweis">
Schon auf dieser Breite bleibt oben für das Feld
kaum etwas übrig, denn das Label behält seine
Breite. Unten passiert nichts, weil beide die volle
Breite für sich haben. Noch schmaler wird es im
Vollbild über die Viewport-Leiste.
</p> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
padding: 24px;
font-family: system-ui, sans-serif;
font-size: 16px;
line-height: 1.5;
}
.etikett {
margin: 0 0 8px 0;
font-size: 14px;
color: #52525b;
}
.feld {
margin-bottom: 32px;
}
.feld--daneben {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
gap: 12px;
}
.feld--drueber {
display: grid;
gap: 4px;
}
input {
width: 100%;
padding: 8px 16px;
border: 1px solid #d4d4d8;
border-radius: 8px;
font: inherit;
}
.hinweis {
max-width: 60ch;
color: #52525b;
} Ein Label kannst du auf zwei Arten setzen, und die Entscheidung hat Folgen.
Steht es daneben, brauchst du eine feste Spaltenbreite. Die muss zum längsten Label passen, und beim ersten längeren Text stimmt sie nicht mehr. Auf schmalen Bildschirmen bleibt für das Feld selbst kaum etwas übrig. In einer Sprache mit längeren Wörtern bricht die Anordnung ganz.
Steht es darüber, hat es die volle Breite für sich. Es überlebt jede Bildschirmbreite, jede Textlänge und jede Übersetzung, und das Auge läuft in einer geraden Linie von oben nach unten durch das Formular. Deshalb ist das der Normalfall. Der andere ist die Ausnahme mit Begründung.
Das Raster
<form class="formular">
<div class="feld"><label for="name">Name</label><input type="text" id="name"></div>
<div class="feld"><label for="mail">E-Mail</label><input type="email" id="mail"></div>
<div class="feld feld--breit"><label for="nachricht">Nachricht</label><textarea id="nachricht" rows="3"></textarea></div>
</form>
<p class="hinweis">
Name und E-Mail sind kurz und teilen sich eine Zeile.
Die Nachricht geht über beide Spalten, weil ein
halbbreites Textfeld niemandem hilft. Zwei Spalten
sind es hier bei jeder Breite, nur schmalere; das
Umschalten auf eine Spalte kommt erst in der
Aufgabe. Wie es mit Luft aussieht, siehst du, wenn
du ins Vollbild gehst.
</p> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
padding: 24px;
font-family: system-ui, sans-serif;
font-size: 16px;
line-height: 1.5;
}
.formular {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
max-width: 640px;
}
.feld {
display: grid;
gap: 4px;
}
.feld--breit {
grid-column: span 2;
}
label {
font-size: 14px;
color: #3f3f46;
}
input,
textarea {
width: 100%;
padding: 8px 16px;
border: 1px solid #d4d4d8;
border-radius: 8px;
font: inherit;
resize: vertical;
}
.hinweis {
max-width: 60ch;
margin-top: 24px;
color: #52525b;
} Ein Formular ist ein Raster. Auf breiten Bildschirmen teilen sich kurze Felder wie Vorname und Nachname eine Zeile, und lange Felder bekommen die volle Breite.
Die Feldgruppe selbst ist dabei auch ein kleines Raster, mit Label und Feld untereinander und wenig Abstand. Zwei Raster stecken also ineinander, und das ist ganz normal. Keins von beiden weiß etwas vom anderen.
Mit grid-column: span 2 geht ein Feld über beide Spalten. Das Nachrichtenfeld gehört dazu, denn ein halbbreites Textfeld hilft niemandem. Man schreibt dort mehrere Sätze, und die brauchen Zeilenlänge.
Ein Stolperstein dabei. Ist das Formular auf schmalen Bildschirmen einspaltig, darf span 2 dort nicht gelten. Will ein Element zwei Spalten überspannen, wo es nur eine gibt, legt der Browser eine zweite an. Und plötzlich ist das Formular doch zweispaltig, nur schlechter. Deshalb kommt das Überspannen in dieselbe Media Query wie die zweite Spalte.
<form class="formular">
<div class="feld"><label for="name">Name</label><input type="text" id="name"></div>
<div class="feld"><label for="mail">E-Mail</label><input type="email" id="mail"></div>
<div class="feld feld--breit"><label for="nachricht">Nachricht</label><textarea id="nachricht" rows="3"></textarea></div>
</form> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
padding: 24px;
font-family: system-ui, sans-serif;
font-size: 16px;
line-height: 1.5;
}
.formular {
display: grid;
gap: 16px;
max-width: 640px;
}
.feld {
display: grid;
gap: 4px;
}
/* So nicht: span 2 gilt für jede Breite. Wo es nur eine
Spalte gibt, legt der Browser für das Feld eine
zweite an. */
.feld--breit {
grid-column: span 2;
}
@media (min-width: 48rem) {
.formular {
grid-template-columns: 1fr 1fr;
}
}
label {
font-size: 14px;
color: #3f3f46;
}
input,
textarea {
width: 100%;
padding: 8px 16px;
border: 1px solid #d4d4d8;
border-radius: 8px;
font: inherit;
resize: vertical;
} Im Beispiel steht die zweite Spalte richtig in der Media Query, das span 2 aber davor. In der schmalen Spalte neben dem Editor siehst du das Formular deshalb zweispaltig. Name und E-Mail teilen sich eine Zeile, in zwei ungleichen Spuren von rund 162 und 154 Pixeln, die niemand bestellt hat, und darunter überspannt die Nachricht beide. Im Vollbild sieht alles richtig aus. Am Schreibtisch fällt der Fehler deshalb nicht auf.
Die Button-Zeile
<div class="aktionen">
<button class="button button--sekundaer" type="button">Abbrechen</button>
<button class="button button--primaer" type="button">Absenden</button>
</div>
<p class="hinweis">
Wird der Platz zu eng, rutscht der zweite Button in
eine neue Zeile, statt dass beide zusammengedrückt
werden. Die Voreinstellung Handy ist dafür noch zu
breit: trag in der Leiste darüber eine Breite von
Hand ein, etwa 280.
</p> *,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
padding: 24px;
font-family: system-ui, sans-serif;
font-size: 16px;
line-height: 1.5;
}
.aktionen {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 12px;
}
.button {
min-height: 44px;
padding: 8px 16px;
border: 2px solid #2563eb;
border-radius: 8px;
font: inherit;
cursor: pointer;
}
.button--primaer {
color: #ffffff;
background-color: #2563eb;
}
.button--sekundaer {
color: #1d4ed8;
background-color: transparent;
}
.hinweis {
max-width: 60ch;
margin-top: 24px;
color: #52525b;
} Am Ende stehen ein bis zwei Buttons, und dafür ist Flexbox richtig. Sie sollen rechtsbündig nebeneinanderstehen, mit Abstand dazwischen, und nicht in ein Raster gezwängt werden. justify-content: flex-end schiebt sie ans Ende, gap hält sie auseinander.
flex-wrap: wrap gehört dazu. Wird es eng, rutscht der zweite Button in eine neue Zeile, statt dass beide so schmal werden, dass ihre Beschriftung umbricht.
Rechts außen landet der Blick zuletzt und der Daumen zuerst, und dort steht die wichtigste Aktion. Abbrechen steht links davon und sieht ruhiger aus, damit niemand aus Versehen den falschen Button trifft.
Was du dabei nicht siehst
Die Rückmeldung. Im Ruhezustand sieht ein Formular am besten aus, und ob es wirklich passt, zeigt sich erst, wenn jemand es benutzt. Dann kommen der Fokusring beim Durchtabben, die rote Markierung nach einer falschen Eingabe und der gesperrte Button während des Absendens.
Einmal mit der Tastatur durch das ganze Formular dauert zwanzig Sekunden. Das mache ich, bevor ich eins für fertig halte.
In der Aufgabe stehen die Felder des Kontaktformulars noch einfach untereinander.
Zum Mitnehmen
Labels stehen über ihren Feldern, und für die Abstände sorgt das Raster. Eine zweite Spalte gibt es erst ab dem Breakpoint, und jedes span 2 gehört zu ihr. Die Buttons stehen in einer Flex-Zeile, die Hauptaktion ganz rechts.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 4 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.