9 Tipps fĂĽr benutzerfreundliche Formulare – Teil 2: HTML & (S)CSS

Heute lernen wir etwas ĂĽber die Programmierung von Web-Formularen. Im ersten Teil ging es um visuelle Verbesserungen und GrĂĽnde dafĂĽr. Jetzt aber nehmen wir die Programmierung in HTML & CSS dahinter unter die Lupe – wir werden kein JavaScript verwenden, d. h. es geht nur ums Styling der Formular-Elemente.

Teil 1: 9 Tipps fĂĽr benutzerfreundliche Formulare – UX Design
Teil 2: 9 Tipps fĂĽr benutzerfreundliche Formulare – HTML & (S)CSS (liest du gerade)

Disclaimer #1: Das ist kein Anfänger-Tutorial. Du solltest HTML & CSS lesen können damit dir der Beitrag hilft. Ebenso ist SCSS für den unteren Teil von Vorteil, wobei wenn du schon CSS lesen/schreiben kannst, ist SCSS nur ein kleiner Schritt.

Disclaimer #2: In Teil 1 haben wir abschlieĂźend Verbesserungen beschrieben, die wir angedacht, aber nicht umgesetzt haben. HierfĂĽr haben wir schlussfolgernd keine Code-Beispiele. Konkret geht es um die Punkte 7.-9. des vorherigen Artikels.

Ausgangspunkt (HTML & CSS)

Wir haben ursprĂĽnglich ein sehr schlichtes Design fĂĽr unsere Felder verwendet:

UrsprĂĽngliches Formular-Feld Design

Um es zu verbessern, haben wir zuerst Problemfelder identifiziert – wie im ersten Blog-Artikel beschrieben. Generell haben es zuvor unsere Formular-Felder nur unzufriedenstellend geschafft zu kommunizieren, was wir erreichen wollen – nämlich: „Ich bin ein Feld, interagiere mit mir/fülle mich aus.“.

HTML-Code

<label>E-Mail
  <input type="email" placeholder="thomas@mustermann.com" size="30">
</label>

CSS-Code

::placeholder {
  color: rgba(255, 255, 255, 0.8);
}

label {
  font-size: 0.85rem;
  display: flex;
  flex-direction: column;
}

input {
  font-size: 1rem;
  margin-top: 0.25em;
  background-color: transparent;
  color: white;
  border: 0;
  border-bottom: solid 1px currentColor;
  padding: 0.5em 1em 0.5em 0;
  outline: 0;
}

Zwischenstand (Live-Code)

Klicken Sie auf den unteren Button, um den Inhalt von jsitor.com zu laden.

Inhalt laden

1. Kontrast: Hebe das Feld hervor

Wichtig ist, dass Formular-Felder auch solche erkannt werden, sprich das Formular-Feld soll sich visuell vom Hintergrund bzw. anderen Elementen unterscheidet. Die Entscheidung fiel darauf, den Rahmen und die Hintergrundfarbe vom Feld anzupassen.

Vorher: Wenig Kontrast zum Hintergrund
Nachher: Feld zeichnet sich gut vom Hintergrund ab

Diese Änderungen werden mit CSS durchgeführt (Unser HTML bleibt vorerst unverändert). Die Innen- & Außenabstände – und natürlich die Farben – mussten angepasst werden:

/* […] */

input {
  font-size: 1rem;
  color: white;
  outline: 0;
  margin-top: 0.75em;
  padding: 0.75em 1em;
  /* Hintergrund der Seite: #16161D = hsl(240, 14%, 10%) */
  background-color: hsl(240, 14%, 8%);
  border: solid 1px rgba(255, 255, 255, 0.5);
  border-radius: 0.5em;
}

Klicken Sie auf den unteren Button, um den Inhalt von jsitor.com zu laden.

Inhalt laden

2. Platzhalter und User-Text

„Verwende einen ausreichend großen Kontrast zwischen Platzhalter Text und der Eingabe des Benutzers“, habe ich im ersten Artikel geschrieben. Das tun wir auch: die Transparent des Platzhalter-Texts wird verdoppelt, sprich der weiße Text hat die Hälfte der Deckkraft und wird dunkler → der Kontrast stärker.

Eine kleine Ă„nderung im CSS:

/* […] */
::placeholder {
  color: rgba(255, 255, 255, 0.4);
}
/* […] */
Vorher: Nicht ausgefĂĽllt – Platzhalter-Text allein sichtbar
Nachher: Platzhalter-Text ist dĂĽnkler

Zwischenstand (Live-Code)

Klicken Sie auf den unteren Button, um den Inhalt von jsitor.com zu laden.

Inhalt laden

3. Icons

Für die Icons muss die HTML-Struktur etwas ändern werden. Wir brauchen das Icon selbst – hierfür nutzen wir die kostenlosen Heroicons (öffnet in einem neuen Fenster – und ein Container-Element, das das Feld und das Icon gruppiert.

  • Das Icon wird als SVG-Code hinzugefĂĽgt, dadurch können wir es mit CSS stylen.
  • Das Container-Element ist notwendig, um das Icon zu positionieren.
Vorher: Ohne Icon
Nachher: Feld erhält mit Icon ein zusätzliches Unterscheidungsmerkmal

HTML

Interessant ist, dass das SVG-Icon innerhalb des <div>-Containers nach dem <input>-Tag platziert wird. Das ermöglicht mithilfe des CSS-Operators + später das Styling des SVGs, falls sich etwas mit dem Feld tut.

<label>E-Mail *
  <div class="field-plus-icon-container">
    <input type="email" placeholder="thomas@mustermann.com" size="30" required>
    <!-- Icon -->
    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
        d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
    </svg>
  </div>
</label>

SCSS

Zum ersten Mal verwende ich an dieser Stelle auch SCSS um CSS zu erzeugen. SCSS erweitert – vereinfacht gesagt – CSS um nützliche Funktionen. Wir verwenden davon:

  • Variablen um Code wiederzuverwenden (fĂĽr z.B. Farbcodes) und
  • Nesting um Elementen eindeutig(er) zu identifizieren: Es werden die CSS-Selektoren ineinander geschachtelt (wie HTML-Elemente auch) und ermöglichen damit ein saubereres Arbeiten.
/* […] */

.field-plus-icon-container {
  position: relative;
  display: flex;
  align-items: center;
  margin-top: 0.75em;

  input {
    padding-left: calc(1em + 24px + 0.5em);
  }

  svg {
    position: absolute;
    opacity: 0.4;
    left: 1em;
  }
}

input {
  font-size: 1rem;
  color: white;
  outline: 0;
  padding: 0.75em 1em;
  background-color: hsl(240, 14%, 8%);
  border: solid 1px rgba(255, 255, 255, 0.5);
  border-radius: 0.5em;
}

Zwischenstand (Live-Code)

Klicken Sie auf den unteren Button, um den Inhalt von jsitor.com zu laden.

Inhalt laden

4. + 5. Hover- & Focus-State

Weiterhin unser Ziel: Das Feld soll dem Benutzer signalisieren, dass es interaktiv ist. Sobald die Maus also über dem Feld ist (Hover-State) soll es sich ändern. Ebenso wollen wir eine visuelle Änderung, sobald das Feld bearbeitet werden kann (Focus-State).

Hover-State (vorher): Keine Ă„nderung
Hover-State (nachher): Eingabefeld signalisiert dem Benutzer Interaktivität
Focus-State (vorher): Feld bleibt beim Bearbeiten gleich
Focus-State (nachher): Feld signalisiert, dass es Bearbeitet wird

SCSS

Wie unter 3. Icons erwähnt nutzen wir den CSS-Operators +, um das SVG-Icon zu stylen, sobald sich der „Zustand“ des Feldes ändert. Der Zustand kann beispielsweise durch User-Interaktion geändert werden; der Maus-Cursor liegt über dem Element.

/* […] */

.field-plus-icon-container {
  /* […] */

  input {
    padding-left: calc(1em + 24px + 0.5em);

    &:hover {
      border-color: white;

      + svg {
        opacity: 0.8;
      }
    }

    &:focus {
      border-color: dodgerblue;

      + svg {
        opacity: 0.8;
      }
    }
  }

  svg {
    /* […] */
  }
}

/* […] */

Zwischenstand (Live-Code)

Klicken Sie auf den unteren Button, um den Inhalt von jsitor.com zu laden.

Inhalt laden

6. Fehlerhafte Daten hervorheben

Falls eine Eingabe nicht dem entspricht, was erwartet wird, sollte das dem Benutzer mitgeteilt werden bevor das Formular abgesendet wird. Durch eine veränderte Darstellung; womöglich eine kurze Nachricht. Ersteres haben wir umgesetzt:

Nerd-Fact: Wie im ersten Blog-Beitrag erwähnt, es handelt sich hierbei um eine kosmetische MaĂźnahme zum besseren Benutzer-Erlebnis (UX). Programmiert man Formulare darf sich nicht darauf verlassen, dass Daten aus einem Formular „sauber“ sind – bevor diese weiter verarbeitet werden, mĂĽssen diese immer serverseitig geprĂĽft werden.

Feld signalisiert farblich eine falsche Benutzer-Eingabe

HTML

Zwei kleine Ă„nderungen: Als Erstes wird dem Label ein Sternchen (*) hinzugefĂĽgt, das sich als visuelle Markierung fĂĽr Pflichtfelder etabliert hat. Als zweite Ă„nderung wird dem Formular-Feld (<input>) ein required-Attribut hinzugefĂĽgt. Dies teilt dem Webbrowser mit, dass das Feld als Pflichtfeld zu betrachten ist.

<label>E-Mail *
  <div class="field-plus-icon-container">
    <input type="email" placeholder="thomas@mustermann.com" size="30" required>
    <!-- SVG-Icon […] -->
  </div>
</label>

Optional kann man auch einen Beschreibungstext „Das ist ein Pflichtfeld“ zum Sternchen hinzufügen. Clevererweise löst man das mit einem <abbr> Abkürzungselement (MDN-Dokumentation) (öffnet in einem neuen Fenster, wenn man eine schicke Lösung will und einem Barrierefreiheit am Herzen liegt.

SCSS

Um ein wenig Kontext zu geben; wir treffen folgende Annahmen:

  • Nur Felder mit required-Attribut werden visuell hervorgehoben
  • Nur Felder mit User-Inhalt werden visuell hervorgehoben, sprich die keinen Platzhalter-Text enthalten (input[required]:not(:placeholder-shown) etc.)
$color-success: limegreen;
$color-error: red;
$color-focus: dodgerblue;

/* […] */

input {
  /* […] */

  // Nur Felder mit required-Attribut werden visuell hervorgehoben
  &[required] {

    &:invalid {
      box-shadow: none;
    }

    &:not(:placeholder-shown):invalid {
      border-color: $color-error;

      + svg {
        opacity: 0.8;

        path {
          stroke: $color-error;
        }
      }
    }

    &:focus:valid,
    &:not(:placeholder-shown):valid {
      border-color: $color-success;

      + svg {
        opacity: 0.8;
      }
    }
  }
}

Als kleines Extra wird noch das Standard-Styling von Firefox-Webbrowser überschrieben. Firefox markiert nämlich nicht-valide Felder automatisch mit einem roten Rahmen.

// Firefox: Remove default validation styles
:-moz-ui-invalid,
:-moz-submit-invalid {
  box-shadow: none;
}

Zwischenstand (Live-Code)

Klicken Sie auf den unteren Button, um den Inhalt von jsitor.com zu laden.

Inhalt laden

Vollständiger Code

Hier findest du den gesamten Code für ein Formular-Feld + den SCSS-Code zum Stylen. Es handelt sich um ein Pflichtfeld für eine E-Mail-Adresse. In einem echten Projekt gehen wir noch einige Schritte weiter und fügen Fehlermeldungen hinzu und setzen zusätzliche Maßnahmen, die die Barrierefrei verbessern.

HTML

<label>E-Mail *
  <div class="field-plus-icon-container">
    <input type="email" placeholder="thomas@mustermann.com" size="30" required>
    <!-- Icon -->
    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
        d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
    </svg>
  </div>
</label>

SCSS

$color-success: limegreen;
$color-error: red;
$color-focus: dodgerblue;

html,
body {
  height: 100%;
  background-color: #16161D;
  color: white;
  font-family: sans-serif;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
}

::placeholder {
  color: rgba(255, 255, 255, 0.4);
}


label {
  font-size: 0.85rem;
  display: flex;
  flex-direction: column;
}

.field-plus-icon-container {
  position: relative;
  display: flex;
  align-items: center;
  margin-top: .75em;

  input {
    padding-left: calc(1em + 24px + .5em);

    &:hover {
      border-color: white;

      + svg {
        opacity: 0.8;
      }
    }

    &:focus {
      border-color: $color-focus;

      + svg {
        opacity: 0.8;
      }
    }
  }

  svg {
    position: absolute;
    opacity: .4;
    left: 1em;
  }
}

input {
  font-size: 1rem;
  color: white;
  outline: 0;
  padding: .75em 1em;
  background-color: hsl(240, 14%, 8%);
  border: solid 1px rgba(255, 255, 255, 0.5);
  border-radius: .5em;

  &[required] {

    &:invalid {
      box-shadow: none;
    }

    &:not(:placeholder-shown):not(:focus):invalid {
      border-color: $color-error;

      + svg {
        opacity: 0.8;

        path {
          stroke: $color-error;
        }
      }
    }

    &:focus:valid,
    &:not(:placeholder-shown):valid {
      border-color: $color-success;

      + svg {
        opacity: 0.8;
      }
    }

  }
}

// Firefox: Remove default validation styles
:-moz-ui-invalid,
:-moz-submit-invalid {
  box-shadow: none;
}

Fazit

Für deine Besucher es ist wünschenswert möglichst einfach bedienbare Formulare auf deiner Webseite zu haben. Wie du jetzt gesehen hast, braucht es auch nicht sonderlich viel Code um deine Formulare mit sinnvollem User-Feedback auszustatten.

Falls du dich mehr fĂĽr die Details der Design-Entscheidungen interessiert empfehle ich dir den ersten Teil zum Thema Formular-Design.

Wenn dir dieser Beitrag geholfen hat, dann teile ihn und wenn du Fragen hast, schreibe diese doch einfach in die Kommentare!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.