Finger-freundliche numerische Eingaben mit `inputmode`

Avatar of Ollie Williams
Ollie Williams am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Formulare sind oft ein Albtraum auf Mobilgeräten. Wir können den Prozess so schmerzfrei wie möglich gestalten, indem wir auf den Kontext reagieren. Eingabefelder, die numerische Werte erwarten, sollten eine numerische Benutzeroberfläche haben. Das Aufrufen einer Nummerntastatur auf kleinen Bildschirmen ist auf den meisten Plattformen einfach – verwenden Sie einfach ein <input type="number">.

A screenshot of the iOS number keyboard with keys for numbers one through ten.

Diese große, fingerfreundliche numerische Tastatur hilft, Frustration bei den Benutzern zu vermeiden. Allerdings ist type="number" nicht für alle Zahlen geeignet.

Auf (den meisten) größeren Bildschirmen werden Nummern-Inputs mit einem Inkrement-/Dekrementierknopf geliefert. Das ist eine nützliche Benutzeroberfläche, die wir standardmäßig kostenlos erhalten. Sie macht diese Art von Eingabe jedoch völlig ungeeignet für beispielsweise eine Kreditkartennummer.

A default number input that displays the up and down arrows that allow users to increase and decrease numbers in the field.
Die Standard-Benutzeroberfläche für Nummern-Inputs sieht in allen Desktop-Browsern ungefähr so aus

Die Spezifikation selbst macht dies deutlich.

Der Zustand `type=number` ist nicht für Eingaben geeignet, die zufällig nur aus Zahlen bestehen, aber keine streng genommenen Zahlen sind. Zum Beispiel wäre er für Kreditkartennummern oder US-Postleitzahlen ungeeignet. Eine einfache Methode, um zu bestimmen, ob `type=number` verwendet werden soll, ist zu überlegen, ob die Eingabesteuerung eine Spinbox-Oberfläche (z. B. mit "Auf"- und "Ab"-Pfeilen) haben sollte. Eine Kreditkartennummer um 1 in der letzten Ziffer falsch zu haben, ist kein kleiner Fehler, sondern genauso falsch, wie jede Ziffer falsch zu haben. Daher wäre es für den Benutzer nicht sinnvoll, eine Kreditkartennummer mit "Auf"- und "Ab"-Schaltflächen auszuwählen. Wenn eine Spinbox-Oberfläche nicht geeignet ist, ist `type=text` wahrscheinlich die richtige Wahl (möglicherweise mit einem `pattern`-Attribut).

Es ist einfach, die Auf- und Ab-Schaltflächen mit CSS zu verstecken

input[type="number"] {
  -moz-appearance: textfield;
}
input[type="number"]::-webkit-inner-spin-button, 
input[type="number"]::-webkit-outer-spin-button { 
  -webkit-appearance: none; 
  margin: 0; 
}

Es ist wichtig zu beachten, dass dies nicht der einzige Unterschied zwischen einer Nummer- und einer Texteingabe ist. Sie sollten der Spezifikation in diesem Punkt unbedingt folgen! Einige ältere Browser entfernen führende Nullen für Nummerneingaben, was ein großes Problem für US-Postleitzahlen wäre. Das oft nützliche Attribut `maxlength` wird bei Nummern-Inputs ignoriert.

Warum sollte jemand eine so nützliche Eingabe ablehnen?

Die Antwort liegt in der Validierung und der falschen Verwendung der Eingabe. Die Nummerneingabe führt standardmäßig eine Bereinigung der Eingaben durch. Wenn ein Benutzer etwas eingibt, das keine gültige Zahl ist, ist der Wert ein leerer String – unabhängig davon, was der Benutzer auf dem Bildschirm sieht.

Diese Bereinigung der Eingaben kann Entwickler in die Irre führen, und es gibt keine Möglichkeit, sie zu deaktivieren. Wenn Sie Eingaben zulassen möchten, die keine gültige Zahl sind, verwenden Sie nicht type="number".

A screenshot showing a number input that is filled with numbers and includes dashes between some of the numbers.
Nummerneingabe in Chrome. Dies mag eine gültige Eingabe für Ihren Anwendungsfall sein, ist aber in den Augen der Nummerneingabe illegitim.
var numberinput = document.querySelector('input[type="number"]')
numberinput.value // will be ""

Das entspricht vielleicht nicht dem, was Sie intuitiv erwarten würden. Wenn Sie jedoch die Spezifikation befolgen und die Nummerneingabe nur für das verwenden, wofür sie konzipiert ist – tatsächliche Zahlen –, ist dieses Verhalten unproblematisch.

Alternativen für Nummerneingaben

iOS-Lösung: Verwenden Sie das `pattern`-Attribut für eine Texteingabe

Auf iOS-Geräten wird durch die Verwendung des `pattern`-Attributs mit dem Wert `[0-9]*` die numerische Tastatur aufgerufen. Dies funktioniert nur mit diesem exakten Muster – Sie können keine zusätzlichen Zeichen zulassen.

<label for="creditcard">credit card number:</label> <input pattern="[0-9]*" type="text" name="creditcard">
The iOS number keyboard that displays only numbers one through ten and no other special characters.
iOS mit `pattern`-Attribut

Bedenken Sie, dass ein iPhone es dem Benutzer nicht erlaubt, den Tastaturtyp zu ändern, wenn diese Tastatur angezeigt wird. Stellen Sie sicher, dass dies die einzigen Tasten sind, die er benötigt, um die Eingabe korrekt auszufüllen.

Wenn Sie auf iOS eine Tastatur mit großen numerischen Tasten anzeigen möchten, müssen Sie das `pattern`-Attribut auch bei Nummerneingaben verwenden. Andernfalls erhalten Sie kleine und fingerfreundliche Schaltflächen

A screenshot of the iOS keyboard displaying both numbers and letters.
iOS-Tastatur für <input type="number">

Eine bessere Lösung: `inputmode`

inputmode ist seit einigen Jahren eine WHATWG-Spezifikation und wurde endlich von Chrome ab Version 66 implementiert

Diese Browser-Support-Daten stammen von Caniuse, wo es weitere Details gibt. Eine Zahl gibt an, dass der Browser die Funktion ab dieser Version und aufwärts unterstützt.

Desktop

ChromeFirefoxIEEdgeSafari
6695Nein79Nein

Mobil / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712712.2-12.5

Für die größtmögliche Kompatibilität kann es mit dem `pattern`-Attribut für iOS kombiniert werden

<label for="creditcard">credit card number:</label> <input inputmode="numeric" pattern="[0-9]*" type="text" name="creditcard">

Dies gibt Entwicklern die volle Kontrolle über die mobile Benutzeroberfläche ohne zusätzlichen Ballast. Es macht die Benutzeroberfläche fingerfreundlich und ist vielseitiger als das `pattern`-Attribut, da wir beliebige Zeichen zulassen können. Es steuert eine Sache – und nur eine Sache. `inputmode` ist eine großartige Lösung für Fälle, in denen die Verwendung von `type="number"` unangemessen ist.

Manche Leute würden weiter gehen und `type="number"` ganz aufgeben, sobald `inputmode` bessere Unterstützung hat. Ich bin nicht davon überzeugt, dass das weise ist, aber `type="number"` kann problematisch sein.

if (numberInput.validity.valueMissing) {
errorMessage.textContent = "field must not be empty"
}
A screenshot of a number input filled with numbers and special characters with an error message below it that informs the user the field is empty.
Im Gegensatz zum menschlichen Auge ist das Feld leer…

Wenn Sie ausdrücklich auf leere Nummerneingaben hinweisen möchten, müssen Sie

if (numberInput.validity.valueMissing && !numberInput.validity.badInput) {
errorMessage.textContent = "field must not be empty"
}

Laut Google brechen Benutzer Käufe auf Mobilgeräten doppelt so oft ab wie auf Desktops. Umsätze auf Handys machen nur ein Drittel aller abgeschlossenen Onlinekäufe aus. Es ist klar, dass die Leute es nicht tolerieren, sich durch schlecht gestaltete Formulare zu quälen und auf winzige Eingaben zu tippen. Die Dateneingabe muss mühelos sein. Obwohl die Browserunterstützung derzeit gering ist, warten wir eigentlich nur auf mobile Browser. Desktop-Unterstützung ist weitgehend irrelevant. Die von HTML5 eingeführten Eingabeelemente sind großartig, aber sie verfehlen einige Randfälle. Dies kann einige Lücken füllen.