2 Punkte von GN⁺ 2024-10-29 | 1 Kommentare | Auf WhatsApp teilen
  • HTML-Formulare verfügen bereits über native Validierungsfunktionen wie required, type="email", pattern, maxlength und setCustomValidity, doch in der Praxis werden sie gemessen am Funktionsumfang wenig genutzt
  • Das besonders mächtige setCustomValidity kann beliebige Validierungslogik und komplexe Fälle abdecken, wird aber nur als DOM-Methode bereitgestellt und passt daher schlecht zu deklarativen Komponenten
  • In Umgebungen wie React greifen für eine korrekte Validierung von Anfangswerten useRef, useLayoutEffect und onChange ineinander, und dieselbe Validierungslogik wird leicht beim initialen Rendern und im Change-Handler dupliziert
  • Mit einer attributbasierten Abstraktion wie custom-validity ließen sich Validierungen mit Abhängigkeiten zwischen Zustand und Eingabe, etwa asynchrone Prüfungen auf doppelte Benutzernamen oder Passwortbestätigungen, an einer Stelle ausdrücken
  • Die geringe Verbreitung nativer Formularvalidierung liegt weniger an fehlenden Funktionen als an der Benutzbarkeit der API; eine deklarative API in der HTML-Spezifikation würde deutlich mehr Einsatzmöglichkeiten eröffnen

Was HTML-Formularvalidierung bereits bietet

  • Die einfachste Möglichkeit, leere Eingaben zu verhindern, ist das Hinzufügen des Attributs required
  • Eingabebeschränkungen lassen sich grob auf drei Arten setzen
    • Verwendung von Eingabetypen wie type="email", type="number" oder type="url"
    • Verwendung von Constraint-Attributen wie pattern und maxlength
    • Verwendung der DOM-Methode setCustomValidity eines Eingabefelds
  • setCustomValidity ist das mächtigste Mittel, weil es beliebige Validierungslogik und komplexe Fälle behandeln kann
  • Die ersten beiden Ansätze lassen sich als HTML-Attribute deklarieren; setCustomValidity unterscheidet sich dadurch, dass ein Methodenaufruf erforderlich ist
  • Als Referenz zum Unterschied zwischen DOM-Attributen und Properties ist Attributes vs Properties verlinkt

Wo setCustomValidity unbequem wird

  • setCustomValidity wird ausschließlich als Methode ohne entsprechendes HTML-Attribut bereitgestellt
  • Übergibt man einen String, wird die Eingabe in den Zustand invalid versetzt, und der Browser zeigt diesen String als Grund für die fehlgeschlagene Validierung an
  • Übergibt man einen leeren String, wird die Eingabe valid, sofern keine anderen Constraints greifen
  • Um ein Verhalten wie bei required selbst zu implementieren, muss bei jeder Wertänderung setCustomValidity aufgerufen werden
  • Allerdings ist eine Eingabe anfangs im Zustand valid; wenn man direkt nach dem Zurücksetzen einer Komponente den Submit-Button drückt, kann die Formularübermittlung durchgehen
    • Denn selbst bei leerem Wert wird der Validierungscode erst ausgeführt, wenn ein Change-Event auftritt
    • Um auch den Anfangswert korrekt zu erfassen, muss dieselbe Validierung bereits beim Mounten der Komponente ausgeführt werden

Mehr Boilerplate in deklarativen Komponenten

  • Wenn auch Anfangswerte validiert werden sollen, wird der Code schnell repetitiv und unhandlich
  • Besonders drei Probleme entstehen dabei
    • Die Validierungslogik wird im onChange-Handler und in der initialen Renderphase dupliziert
    • Der initiale Validierungscode liegt vom Eingabeelement entfernt, was die Kohäsion verringert und das Risiko erhöht, nur eine Seite anzupassen
    • Die Kombination aus useRef, useLayoutEffect und onChange wird mit zunehmender Zahl von Eingaben überdimensioniert und ist besonders verwirrend, wenn nur einige Felder customValidity verwenden
  • Diese Komplexität fällt besonders auf, wenn man eine rein imperative API in deklarativen Komponenten verwendet
  • Für CustomValidity gibt es kein Eingabeattribut, mit dem sich ein Wert deklarativ setzen ließe wie bei nativen Validierungsattributen
  • Wenn eine API umständlich ist, kann ihre Verbreitung trotz starker Funktionen gering bleiben; genau das ist ein zentraler Grund für die unzureichende Nutzung nativer Formularvalidierung

Das fehlende Puzzleteil: ein custom-validity-Attribut

  • Benötigt wird eine deklarative Eigenschaft wie custom-validity, die sich direkt am Eingabefeld angeben lässt
  • In deklarativen Frameworks könnte der Validierungszustand damit nahe am Eingabeelement platziert werden
  • In der aktuellen HTML Spec gibt es kein echtes custom-validity
  • Für Demo-Zwecke lässt sich dieses Verhalten mit einer Implementierung im Userland nachahmen
  • Als Beispiel für eine produktionsreife Komponente wird eine weiter ausgereifte Implementierung bereitgestellt

Asynchrone Validierung und Abhängigkeiten zwischen Eingaben

  • Validierung in realen Anwendungen kann komplexer sein als lokale Prüfungen
  • Bei einem Benutzernamen muss der Server prüfen, ob der Name bereits verwendet wird; während die Anfrage läuft, sollte das Formular nicht valid sein
  • Das Beispiel nutzt required, um leere Eingaben zu verhindern, und versetzt das Eingabefeld je nach Ladezustand und Antwortergebnis über customValidity in den Zustand invalid
  • Die Implementierung besteht aus zwei Teilen
    • Verwaltung des Anfragezustands zur Prüfung der Eindeutigkeit des Benutzernamens mit useQuery aus react-query
    • Verwendung einer benutzerdefinierten <Input />-Komponente, die eine customValidity-Prop entgegennehmen kann
  • Dieser Ansatz kann den gesamten asynchronen Validierungsfluss einschließlich Lade-, Fehler- und Erfolgszustand in einer einzigen Eigenschaft ausdrücken
  • Ein weiteres Beispiel ist ein Formular, das die erneute Eingabe eines Passworts verlangt und damit die Validierung voneinander abhängiger Eingabefelder behandelt

Fazit

  • setCustomValidity ist ein mächtiges Werkzeug, das verschiedenste Validierungsanforderungen abdecken kann
  • Entscheidend für die tatsächliche Nutzung ist nicht nur, dass eine Funktion existiert, sondern auch eine API, die ihre Verwendung einfach macht
  • Eine deklarative Abstraktion wie custom-validity würde native Formularvalidierung natürlicher nutzbar machen
  • Es ist zu hoffen, dass eine solche Funktion eines Tages nativ in die HTML-Spezifikation aufgenommen wird

1 Kommentare

 
GN⁺ 2024-10-29
Meinungen auf Hacker News
  • Als ich zuletzt nachgesehen habe, konnten moderne Webbrowser das Aussehen der eingebauten HTML-Validierungsmeldungen immer noch nicht stylen: https://stackoverflow.com/questions/5328883/how-do-i-style-t...
    Wäre es wenigstens so, dass Chrome und Firefox den UI-Richtlinien der jeweiligen OS-Plattform folgten und die Meldungen wie systemeigene Tooltips à la title="" wirkten, wäre es weniger schlimm. Chrome verwendet aber ein gelb/oranges Icon, schwarzen Text auf weißem Hintergrund und eine Sprechblase mit fest abgerundeten Ecken, was stark mit der Ästhetik des aktuellen Projekts kollidiert.
    Früher erlaubte Chrome das Styling von Validierungsmeldungen über vendor-präfixierte Pseudoelement-Selektoren, entfernte diese Funktion aber und brachte sie nie zurück. Das landet damit auf meiner willkürlichen Liste von Ärgernissen wie „Gebt mir bitte eine native HTML-Combobox“ und „Warum ist das immer noch eine schwer bedienbare Strg-Klick-Box statt einer Liste von Checkboxen?“

    • Das Problem hier ist weniger das fehlende Custom Styling an sich, sondern dass es ziemlich einfach ist, den nativen validity-Status eines Eingabefelds auszulesen und nach eigenen Vorstellungen zu rendern.
      Das eigentliche Problem ist, Änderungen dieses Gültigkeitsstatus zuverlässig zu abonnieren. Es gibt zwar Validitäts-Events, aber sie werden nicht immer ausgelöst. Wenn man den Formularzustand programmatisch ändert, etwa mit form.reset() oder input.value = '...', werden diese Events nicht getriggert.
      Ich halte das für ein gutes Thema, das man gesondert untersuchen und der Webplattform vorschlagen könnte.
    • Ich verstehe nicht ganz, warum man sogar so etwas stylen wollen sollte. Farben oder Layouts zur Darstellung sind in Ordnung, aber ab einem gewissen Punkt ist Benutzbarkeit wichtiger als Branding.
    • Stimmt. Allerdings kann man die Standardmeldungen ausblenden und durch eigene Meldungen ersetzen. Die Vorteile der Formularvalidierung bleiben trotzdem erhalten.
    • In dieser Hinsicht ist auch das Styling eines einzelnen select nicht so einfach, wie es eigentlich sein sollte.
  • Das Größte und am leichtesten Umzusetzende, das trotzdem zu selten genutzt wird, ist die Verwendung konkreter Werte für das type-Attribut wie email, number oder url.
    Auf Mobilgeräten kann dadurch die passende Tastatur angezeigt werden, was die User Experience deutlich verbessert.

    • Ich vermeide type=number und nutze stattdessen type=text inputmode=numeric. So erscheinen keine Pfeil-Buttons, die die meisten Nutzer für die Zahleneingabe nicht brauchen, und unter iOS ist auch die Tastatur besser.
    • Es gibt erstaunlich viele Stellen, die in einem Login-Formular „email“ anzeigen, aber nicht den richtigen type setzen.
    • Bei date-Eingaben habe ich das ebenfalls sehr oft gesehen. Jede Frontend-Bibliothek hat ihr eigenes Datums-Widget, und viele davon sehen auf kleinen Bildschirmen miserabel aus.
      Für dieses eine Widget muss man zusätzlich JS und CSS einbinden, manche hängen sogar von jQuery ab. Natürlich gibt es Varianten mit sehr vielen Einstellungsmöglichkeiten, aber für sehr geringe Kosten bekommt man ein Widget, das überall okay ist und nativ wirkt, die Anforderungen meist erfüllt und um das man sich ohne Update- oder CDN-Sorgen nicht weiter kümmern muss.
    • Leider sind number-Eingaben unzureichend und je nach Browser inkonsistent. Am Ende bin ich immer wieder zu JavaScript-Validierung zurückgekehrt.
    • In letzter Zeit musste ich sicherstellen, keine komplexeren Eingabeelemente zu verwenden. Aus verschiedenen Gründen mussten Eingaben über eine auf der Seite implementierte Bildschirmtastatur gesteuert werden.
      Mit normalen Eingaben ist das gerade noch machbar, aber spezielle Eingaben unterstützen noch weniger Events.
  • Mein Produkt hat ein Accessibility-Audit nicht bestanden, weil es native HTML-Formularvalidierung verwendet, und die offizielle Empfehlung war, eine eigene Validierungsschicht zu implementieren. Dieser Empfehlung stimme ich auch zu.
    Die native HTML-Validierung hat viele Schwächen, und ehrlich gesagt ist die visuelle Anpassbarkeit nicht einmal die größte Sorge. Sie ist allerdings so etwas wie der letzte Sargnagel.
    Wenn man zum Beispiel mehrere Fehler pro Feld auf einmal anzeigen will, bleibt einem nur, Strings aneinanderzuhängen. Etwa: „Eine Zahl ist erforderlich. Ein Symbol ist erforderlich. Muss länger als 10 Zeichen sein.“ Das ist eine schlechte User Experience und auch schlecht für die Accessibility, weil man den zusammengehängten String im Accessibility Tree nicht navigieren kann. Das ist kein Implementierungsproblem, sondern ein Problem der Spezifikation selbst. Es macht keinen Spaß, wenn Nutzer Validierungsfehler wie beim Whac-a-Mole abarbeiten müssen, also sollte man mehrere Fehler auf einmal anzeigen können.
    Schlecht ist auch die Browser-Abhängigkeit. Man hat keine Kontrolle, und die Implementierungen sind meist miserabel. Chrome zeigt beim Fokus ein Popup an; es ist ein Popup, sieht wie ein Modal aus und kann nicht alle Formularfehler auf einmal anzeigen, weshalb es an sich schon nicht besonders barrierefrei ist. Wichtige Informationen nicht in Popups anzuzeigen, gehört zu den Accessibility-Grundlagen, aber Browser können nicht viel anderes tun, ohne das eigentliche Dokument zu stören.
    Formularweite Fehler, die keinem bestimmten Feld zugeordnet sind, benötigen weiterhin Custom Validation. Etwa Fehler wie „Feld A und Feld B sind nicht miteinander vereinbar“, und dann ist es besser, gleich einen konsistenten Validierungsansatz zu haben.
    Wenn man Custom Inputs hat, die nicht zu nativen Eingabetypen passen, braucht man aus Konsistenzgründen versteckte Inputs, was wiederum die Accessibility kaputtmacht. Das zu beheben ist am Ende genauso schwierig, wie gleich ein eigenes barrierefreies Validierungssystem zu bauen.
    Die customValidity-API ist imperativ und umständlich zu benutzen. Wenn man keine schrecklichen Meldungen wie „Dieses Feld ist ungültig“ haben will, ist es praktisch keine Option, auf Custom Validity zu verzichten. Deshalb ist HTML-Formularvalidierung schlecht.

    • Es ist schon ironisch, dass eine vom Browser bereitgestellte Funktion die Accessibility-Anforderungen nicht erfüllen kann. Schließlich wurde uns immer beigebracht, dass einer der Gründe, die Plattform zu nutzen und semantische Elemente zu verwenden, die Accessibility ist.
      Trotzdem halte ich es für sinnvoll, den nativen Validierungsmechanismus zu nutzen. Man muss für Fehlermeldungen nicht zwingend die nativen Validity-Tooltips verwenden; man kann ValidityState aus input.validity direkt auslesen, die Meldungen nach Wunsch rendern und bei Bedarf mehrere Fehler anzeigen.
      Browser können verbessert werden, und wenn man einen standardisierten Ansatz nutzt, kann man davon profitieren. Die Schlussfolgerung „Wenn man keine Popups verwendet, geht die Accessibility kaputt“ klingt seltsam, aber wenn man ein Audit bestehen muss, kann es nötig sein, diesen Weg zu gehen.
      Auch für Fehler, die keinem bestimmten Feld zugeordnet sind, gibt es Techniken. In meinem Projekt verwenden wir eine HiddenValidationInput-Komponente, die ein unsichtbares, schreibgeschütztes Input erzeugt, um Custom Errors zu rendern, die zu keinem anderen Feld gehören. Man muss sie nur bedingt rendern, daher ist sie in der Praxis ziemlich angenehm zu verwenden.
      Ich stimme völlig zu, dass die customValidity-API imperativ und umständlich ist. Genau darüber habe ich einen Artikel geschrieben, und ich hoffe, dass sich auch dieser Teil mit der Zeit verbessert.
    • Interessant, aber in meiner App implementiere ich all diese Validierung. Formularweite Validierung erledigt der Server. Im Grunde habe ich mehrere Validierungsschichten und nutze alles, was möglich ist.
      Chromes grobes und wenig barrierefreies Design ist ein Chrome-Problem, also werde ich einen Bug Report einreichen.
      Ist mit „Spezifikation“ das hier gemeint? https://html.spec.whatwg.org/multipage/dom.html#concept-elem...
      Ich sehe keinen Abschnitt, der definiert, wie Validierungsmeldungen angezeigt werden müssen. Nicht einmal, dass es überhaupt eine Meldung geben muss.
    • Mich würde interessieren, warum die Auditoren zu dieser Einschätzung gekommen sind.
  • Ehrlich gesagt wirken die Leute, die solche Spezifikationen schreiben, realitätsfern und so, als würden sie das, was sie spezifiziert haben, selbst nicht wirklich benutzen. Für sehr einfache Dinge funktioniert es, aber sobald Formulare sich weiterentwickeln, merkt man irgendwann, dass man besser alles selbst schreibt.

    • Stimmt. Schon für relativ häufige Dinge mit Querverweisen auf andere Felder braucht man fast sofort JS. Wenn der Nutzer zum Beispiel ein Land angegeben hat, kann man die gerade eingegebene Postleitzahl validieren; andernfalls muss man auf die Länderauswahl warten.
      Sobald man mit JS anfängt, ist es viel einfacher, alles in Code zu machen, als an Validierungsattributen herumzudrehen.
    • Stimmt. Es ist großartig, bis man einen Cross-Browser-Datepicker braucht; ab diesem Punkt muss man vieles selbst implementieren. Es ist frustrierend, dass HTML-Formulare nach all den Jahren immer noch so primitiv sind.
    • Die meisten Formularfunktionen stammen aus den frühen 90ern. Vielleicht arbeiten sie nicht im selben Jahrtausend wie einige der Spezifikationsautoren.
  • Wenn eine Checkbox ein Label hat, würde ich mir wünschen, dass das Label ein for-Attribut bekommt, damit man die Checkbox durch Klicken auf das Label ein- und ausschalten kann. Das ist persönlich eines der Dinge, die mich am meisten stören, aber vielleicht bin das nur ich.

    • Es funktioniert auch, wenn man das input mit einem label umschließt. Ich weiß nicht genau, warum Leute dazu neigen, die beiden getrennt zu halten.
      Und ich weiß auch nicht, warum Browser angefangen haben, diese Dinge zu trennen. Aus meiner Sicht sollte nicht der Text Checkboxen und Radiobuttons enthalten, sondern Checkboxen und Radiobuttons sollten den Text enthalten.
    • Du bist nicht der Einzige. Auf barrierefreien Websites, die ADA/WCAG folgen, ist das eine notwendige Funktion.
  • Ein einfaches Beispiel ohne React gibt es hier:
    https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectE...

    • Ich fand es sehr merkwürdig, dass beim Thema standardmäßige HTML-Validierung alle Beispiele mit React gezeigt werden. Wenn man erklären will, wie der Standard funktioniert, sollte man React nicht als Default voraussetzen.
    • Inzwischen dürfte sich das meiste auch nur mit CSS machen lassen. JavaScript braucht man vielleicht nur, um zu verhindern, dass das Standard-Popup erscheint.
  • HTML-Formularvalidierung ist großartig. Es gibt allerdings eine riesige Falle:
    In Firefox für Android funktioniert sie nicht.
    https://bugzilla.mozilla.org/show_bug.cgi?id=1510450

    • Ich nutze Firefox auf allen Mobilgeräten, aber in diesem Fall kann man Entwicklern kaum vorwerfen, Firefox für Android zu ignorieren. Es ist eine API, die alle anderen Browser seit zehn Jahren unterstützen, und die Verantwortung, dieses Durcheinander aufzuräumen, liegt beim Firefox-Team.
      Es lohnt sich nicht, den Standard wegen weniger als 1 % der Nutzer zu ignorieren, die die Fehlermeldungen bei rot markierten Controls nicht sehen können. Je mehr Websites das verwenden, desto größer wird der Druck auf Mozilla, den Browser zu reparieren.
      Das ist keine API wie WebMIDI, die Chrome oder Safari vor der Standardisierung implementiert haben, sondern Teil der ursprünglichen HTML5-Spezifikation.
    • Firefox für Android hat eine kleinere Nutzerbasis als Samsung Internet oder Opera und liegt bei etwa 0,5 %. Zeit in Support dafür zu stecken, ist fast Verschwendung.
      Besonders, wenn man bedenkt, wie wenig Zeit darauf verwendet wird, sicherzustellen, dass Menschen mit Accessibility-Software Websites richtig nutzen können. Wenn man nicht bereit ist, auch über UC Browser zu sprechen, ist dieses Thema hier meiner Ansicht nach kaum erwähnenswert.
    • Als jemand, der Firefox unter Android täglich nutzt, schmerzt am meisten, dass er bei Standards nicht mithält. Besonders bei WebGL-Problemen wie [1] und kleinen Unannehmlichkeiten wie [2].
      Trotzdem ist es ein starkes Argument, uBlock Origin zusammen mit anderen Erweiterungen nutzen zu können.
      [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1884282
      [2] https://bugzilla.mozilla.org/show_bug.cgi?id=1897707
    • Es ist viel schlimmer als „funktioniert nicht“. Die Validierung funktioniert, aber es werden überhaupt keine Fehler angezeigt.
      Wenn die Validierung gar nicht implementiert wäre, wäre das fast besser; so ist es wirklich ein Chaos. Ich habe das vor ein paar Jahren nach langem, schmerzhaftem Debugging herausgefunden, und ich bin sicher, dass ich weder der Erste noch der Letzte war, dem das passiert ist.
    • Ich habe das erst kürzlich bemerkt, nachdem ich unter Android zu Firefox gewechselt bin. Beim Bau einer App wollte ich ein leeres Pflichtfeld abschicken, und es wurde buchstäblich gar nichts angezeigt.
      Bevor ich danach gesucht habe, konnte ich mir nicht vorstellen, was ich übersehen hatte, und es war ziemlich schockierend. Eigene Validierung zu bauen ist okay, aber das hier sollte funktionieren.
  • Man sollte aufpassen, es nicht zu übertreiben.
    Kürzlich wollte ich bei Groupon eine Erstattung bekommen. Der Anbieter, bei dem ich den Groupon gekauft hatte, war unter neuer Geschäftsführung und erkannte meinen Groupon nicht an.
    Das Formular hatte eine Bedingung „mindestens 15 Wörter“, aber egal was ich tat, ich kam nicht durch die Validierung und musste am Ende das HTML inspizieren.
    \w stand für Wortzeichen, \b für Wortgrenze, \s für Whitespace, und Satzzeichen waren buchstäblich überhaupt nicht erlaubt.

    • Ich glaube nicht, dass das speziell ein Problem der HTML-Validierung ist. So etwas passiert bei jeder Art von Validierung. Dieselbe Regel hätte auch serverseitig gelten können, und dann wäre es hoffnungslos gewesen.
    • Das ist auch ein gutes Argument für den Punkt, den ich machen wollte. Vorhandene Validierungsattribute wie pattern sind nett, aber nicht ausreichend.
      Zum Beispiel lässt sich das Beispiel „Passwort wiederholen“ auch ohne setCustomValidity mit dem Attribut pattern umsetzen. Dafür müsste man dynamisch aus dem ersten Eingabewert einen regulären Ausdruck erzeugen.
      Ich habe die Lösungen nicht verglichen, weil der Artikel sonst zu lang geworden wäre, aber der Kernpunkt ist: Mit customValidity wird die Validierung viel klarer und lesbarer. Eine bessere API macht hier einen großen Unterschied.
      Auch die Einschränkung „mindestens 15 Wörter“ ließe sich viel schöner ausdrücken, etwa als value.split(/\s+/).length >= 15.
  • Es gibt Gründe, warum sie weniger genutzt wird. Viele Frameworks und Bibliotheken bieten robuste und gut stylbare Validierungsfunktionen, manche davon sehr ausgefeilt und erweiterbar. Wenn man sich die Mühe nicht machen muss, sollte man sich nicht selbst quälen.

    • Backend-Validierung muss man ohnehin selbst implementieren. Es gibt immer jemanden, der mit einem seltsamen Browser, curl oder einem anderen Tool ohne eingebaute Formularvalidierung an das Formular geht.
      Man kann nicht darauf vertrauen, dass der Client validiert hat oder es korrekt getan hat; das Backend muss Eingaben weiterhin prüfen und das Formular mit Validierungsfehlern für alle Felder anzeigen können.
      Frontend-Validierung ist nur dazu da, Nutzern zu helfen. Aber wenn man sie stylen oder beim Absenden vom Backend aus auslösen will, muss man am Ende doch eigenes Styling implementieren.
    • Stimme zu. Ich versuche, wo möglich, Browser-Standardfunktionen zu verwenden, aber eingebaute Validierung hat sich bei genauerer Betrachtung nie gelohnt.
      Es gibt zu viele Fallstricke, und wenn man komplexere Prüfungen einfach unterstützen will, landet man am Ende doch bei einer Bibliothek.
      Außerdem eröffnet eine Bibliothek je nach Fall die Möglichkeit, Teile des Validierungscodes zwischen Frontend und Backend zu teilen.
      Besonders dieser Artikel scheint ein Problem mit useLayoutEffect zu umgehen, und das sollte man nicht leichtfertig tun.
  • Eine Sache, die ich an HTML-Formularvalidierung nicht mag, ist, dass sie ab dem Laden der Seite läuft. Wenn man zum Beispiel Fehlerzustands-Styling daran koppelt, wird das Formular von Anfang an voller Fehler geladen und kann auf Nutzer einschüchternd wirken.

    • Es gibt die Pseudoklasse :user-invalid, die das bis zu einem gewissen Grad vermeidet. Sie ist allerdings nicht besonders flexibel und reicht je nach Anwendungsfall möglicherweise nicht aus.
      https://developer.mozilla.org/en-US/docs/Web/CSS/:user-inval...
    • Einer der Hauptgründe, warum Leute angefangen haben, JavaScript zu verwenden, war genau das: Fehler erst anzeigen, nachdem ein Formular „berührt“ wurde oder kurz vor dem Absenden.
    • Ich habe nie verstanden, warum das als Standarderlebnis gewählt wurde. Die meisten Nutzer mögen es nicht, wenn alle Formularelemente sie anschreien, bevor sie überhaupt die Gelegenheit hatten, etwas zu tun.
      Man kann das per Skript umgehen, aber an diesem Punkt leistet die Funktion nicht mehr besonders viel. Ich denke, genau das ist der Hauptgrund, warum sie nicht breiter eingesetzt wird.