Textfelder mit dynamischen Labels

Damit uns Entwicklern nicht langweilig wird, denken sich Designer gerne neue Gimmicks für Webseiten aus. Zum Beispiel so etwas schönes wie Textfeld-Labels, die sich beim Fokus auf das Feld verschieben. Ich nenne sie einfach mal "dynamische Labels". Sowas kann man natürlich mit JavaScript realisieren. Oder man missbraucht ein HTML5-Feature für seine Zwecke und kommt ganz ohne JavaScript aus. Ich zeige Euch heute beide Varianten.

Dynamische Labels mit JavaScript

Wir beginnen zunächst einmal mit unserem HTML-Markup. Dieser wird für beide Varianten ähnlich bleiben und sieht wie folgt aus:

<div class="form-group">
  <input type="text" class="form-control form-control-lg" />
  <label>Textfield</label>
</div>

Ich setze beim Markup das Label hinter das Textfeld, damit wir es über den +-Selector ansprechen können. So reicht es aus das Textfeld an sich anzupassen und wir können das Label je nach Zustand des Textfeldes über CSS steuern. Die verwendeten Klassen stammen von Bootstrap und dienen lediglich dazu der Demo ein angenehmeres Design zu verpassen.

Dann definieren wir ein paar grundsätzliche Stile. Wir werden den Zustand des Textfeldes über eine Klasse .filled steuern. Ist diese gesetzt, wissen wir das der Benutzer etwas in das Textfeld eingetragen bzw. das Textfeld fokussiert hat.

.form-group {
  /* necessary */
  position: relative;
}

label {
  /* necessary */
  top: 1.2em;
  left: 1.5em;
  position: absolute;
  z-index: 1;

  /* eye-candy */
  font-size: 0.75em;
  transition: top 0.5s;
}

.form-control,
.form-control:focus {
  /* necessary */
  background: transparent;
  position: relative;
  z-index: 2;
}

.form-control.filled + label {
  top: 0;
}

Wir positionieren das Label absolut hinter dem Textfeld. Dadurch ist es nicht im Weg, wenn der Benutzer ins Textfeld clicken möchte. Das Textfeld müssen wir dann natürlich transparent machen. Standardmäßig schieben wir das Label etwas in die Mitte des Textfeldes, also an die Stelle, an der der Cursor sich befinden wird. Wenn das Textfeld die Klasse .filled bekommt, schieben wir das Label nach oben weg.

Anschließend hängen wir uns noch mit Event-Handlern an den Focus- und Blur-Event der Textfelder dran und fügen jeweils die .filled-Klasse hinzu oder entfernen sie wieder, wenn das Textfeld leer ist.

var textfields = document.querySelectorAll('input[type=text]');
for (var i = 0, len = textfields.length; i < len; i++) {
  // Beim Fokus fügen wir immer die Klasse filled hinzu.
  textfields[i].addEventListener('focus', function (event) {
    event.target.classList.add('filled');
  });

  // Beim Blur-Event checken wir, ob das Textfeld gefüllt ist und 
  // entscheiden dann was wir tun. toggle() nimmt uns hier mit 
  // seinem zweiten Parameter die meiste Arbeit ab.
  textfields[i].addEventListener('blur', function (event) {
    var hasValue = event.target.value !== '';
    event.target.classList.toggle('filled', hasValue);
  });

  // Falls das Textfeld beim Laden bereits befüllt ist, sollten 
  // wir die Klasse entsprechend hinzufügen.
  if (textfields[i].value !== '') {
    textfields[i].classList.add('filled');
  }
}

Unten könnt Ihr das Ergebnis unserer Anstrengungen sehen. classList ist derzeit übrigens bereits in allen aktuellen Browsern unterstützt. Nur der Internet Explorer 11 und darunter machen Probleme mit der toggle-Methode.

Dynamische Labels mit HTML5

Das war wirklich eine Menge Schreibarbeit für so ein kleines Feature. Das muss doch auch einfacher gehen dachte ich mir. Und siehe da, tatsächlich gibt es einen kleinen Trick mit dem man das Ganze auch ohne JavaScript realisieren kann. Wir benötigen dafür zum einen ein placeholder-Attribut und außerdem die Pseudo-Klasse placeholder-shown.

Achja und wusstet Ihr, dass alle Browser ein Leerzeichen als validen Placeholder werten? Aber wie soll uns das nun eigentlich weiter helfen? Geduld, Geduld. Zunächst einmal aktualisieren wir den Markup etwas und fügen ein Placeholder-Attribut hinzu. Dieses "füllen" wir mit einem Leerzeichen.

<div class="form-group">
  <input type="text" placeholder=" " class="form-control form-control-lg" />
  <label>Textfield</label>
</div>

Die Pseudo-Klasse placeholder-shown wird immer dann aktiv, wenn der Platzhalter angezeigt wird. Sprich, wenn das Textfeld leer ist. Alle Stile für das leere Textfeld hängen wir nun also an unsere Pseudo-Klasse.

.form-group {
  /* necessary */
  position: relative;
}

label {
  /* necessary */
  top: 0; <-- Geändert
  left: 1.5em;
  position: absolute;
  z-index: 1;

  /* eye-candy */
  font-size: 0.75em;
  transition: top 0.5s;
}

.form-control,
.form-control:focus {
  /* necessary */
  background: transparent;
  position: relative;
  z-index: 2;
}

.form-control:placeholder-shown + label { <-- Geändert
  top: 1.2em;
}

.form-control:focus + label { <-- Geändert
  top: 0;
}

Tatsächlich müssen wir nun nur ein paar kleinere Anpassungen machen. Die Labels sind nun Standardmäßig nach oben geschoben und nur wenn der Platzhalter angezeigt wird, wandern sie nach unten. Leider unterstützt der Internet Explorer unseren kleinen Trick so gar nicht. Für diesen sind die Labels nun immer in der Position "top: 0;". Ich denke das ist zu verschmerzen. Schaut Euch das Ganze unten in der Demo in Aktion an und lasst mich wissen, was Ihr davon haltet.


Kommentare


Wichtig: Durch den Click auf die obige Checkbox stimmst Du ausdrücklich der Übertragung von Daten an Facebook zu. Die Zustimmung erfolgt einmalig für die Kommentare dieses Artikels und wird nicht gespeichert. Weitere Details kannst Du dem Punkt Social Plugins der Datenschutzerklärung entnehmen.