Signatur
Beschreibung
Die schreibgeschützte Eigenschaft stepMismatch der Schnittstelle ValidityState ist true, wenn der aktuelle Wert eines <input>-Elements nicht auf dem Raster liegt, das durch das Attribut step festgelegt ist. Die Basis dieses Rasters ist der Wert von min. Fehlt min, gilt der Wert von value im HTML (der Standardwert). Gibt es auch den nicht, ist die Basis 0. Bei min="1" und step="2" sind also nur 1, 3, 5 … gültig.
Die Eigenschaft gilt nur für Eingabetypen, die step unterstützen: number, range, date, month, week, time und datetime-local. Bei range kommt sie praktisch nie vor, weil der Browser den Wert automatisch auf den nächsten gültigen Schritt rundet. Bei Datums- und Zeittypen wird step in Tagen, Wochen, Monaten oder Sekunden gerechnet, je nach Typ.
Wenn stepMismatch true ist, ist das Element ungültig: validity.valid wird false und die CSS-Pseudoklasse :invalid greift. Die Eigenschaft ist nützlich, um eigene, verständliche Fehlermeldungen zu erzeugen, etwa mit setCustomValidity(), statt die allgemeine Meldung des Browsers anzuzeigen.
Rückgabewert
true, wenn der Wert nicht zum step-Raster passt, sonst false. Auch false bei leerem Feld oder step="any".Beispiele
Einfache Prüfung eines Zahlenfelds
// HTML: <input id="menge" type="number" min="0" step="5">
const input = document.querySelector('#menge');
input.value = '12';
console.log(input.validity.stepMismatch); // 12 liegt nicht auf dem 5er-Raster
input.value = '15';
console.log(input.validity.stepMismatch);
Eigene Fehlermeldung mit nächstgelegenen gültigen Werten
// HTML: <input id="preis" type="number" min="0" step="0.5">
const preis = document.querySelector('#preis');
preis.addEventListener('input', () => {
preis.setCustomValidity(''); // zurücksetzen, sonst bleibt das Feld ungültig
if (preis.validity.stepMismatch) {
const step = Number(preis.step);
const min = Number(preis.min) || 0;
const wert = preis.valueAsNumber;
const unten = min + Math.floor((wert - min) / step) * step;
const oben = unten + step;
preis.setCustomValidity(
`Bitte in 0,50-€-Schritten eingeben, z. B. ${unten} oder ${oben}.`
);
}
preis.reportValidity();
});
Raster-Basis über min verschieben
const input = document.createElement('input');
input.type = 'number';
input.min = '1';
input.step = '2'; // gültig: 1, 3, 5, ...
for (const v of ['2', '3', '4', '7']) {
input.value = v;
console.log(v, input.validity.stepMismatch);
}
Zeitfeld nur in 15-Minuten-Schritten erlauben
// step bei type="time" wird in Sekunden angegeben
const zeit = document.createElement('input');
zeit.type = 'time';
zeit.step = String(15 * 60); // 900 Sekunden
zeit.value = '09:10';
console.log(zeit.validity.stepMismatch);
zeit.value = '09:15';
console.log(zeit.validity.stepMismatch);
// Wichtig · Fallstricke
- Basis des Rasters: Viele übersehen, dass
min(oder ersatzweise das HTML-Attributvalue) die Basis bestimmt, nicht 0. Beimin="1" step="10"ist 10 ungültig, 11 dagegen gültig. - Standard-Schrittweite: Ohne
step-Attribut gilt beinumberder Wert1. Dezimalzahlen wie1.5sind dann ungültig. Wer beliebige Werte erlauben will, setztstep="any". - Gleitkomma: Browser vergleichen mit einer Toleranz, deshalb erzeugt z. B.
step="0.1"keine falschen Treffer. Wer das Raster in JavaScript selbst nachrechnet, sollte ebenfalls mit Toleranz arbeiten oder auf ganze Zahlen skalieren. - Leere Felder: Ein leeres Feld löst nie
stepMismatchaus. Für Pflichtfelder braucht esrequired(dann greiftvalueMissing). setCustomValidity(): Die eigene Meldung vor jeder Prüfung mitsetCustomValidity('')zurücksetzen, sonst bleibt das Feld dauerhaft ungültig.- Kompatibilität: Wird von allen modernen Browsern unterstützt. Bei
range-Feldern rundet der Browser den Wert selbst, dort ist die Eigenschaft praktisch immerfalse. - Die Prüfung im Browser ersetzt nicht die Prüfung auf dem Server.