Barrierefreie, DSGVO-saubere Formular-Bausteine: sichtbare <label>,
deutliche Fokus-Ringe, eigene Steuerelemente und Spamschutz ohne Captcha. Akzentfarbe über
--akzent in einer Zeile anpassbar.
Input, Select und Textarea mit weichem box-shadow-Fokus-Ring in der Akzentfarbe, eigenem Dropdown-Pfeil als inline data:-SVG und Autofill-Override gegen den weißen Browser-Hintergrund. Sichtbare Labels (BFSG). Vorbild: NDS, Silver Mountain, Bernstein.
Pol 2 · KlarheitAnlass: Einwilligung Kontaktformular
Eigene Checkbox per appearance:none — Browser-Default ist auf dunklem Grund kaum sichtbar. Box mit Akzent-Border, CSS-Häkchen bei :checked, daneben DSGVO-Hinweis mit Datenschutz-Link. Eigener Fokus-Ring für Tastatur. Vorbild: Silver Mountain, Bernstein.
<label class="fx-consent">
<input type="checkbox" name="consent">
<span>Ich habe die <a href="#">Datenschutzerklärung</a> gelesen und willige in die
Verarbeitung meiner Angaben zur Bearbeitung der Anfrage ein. Die Einwilligung ist
jederzeit widerrufbar.</span>
</label>
<style>
.fx-consent{display:flex;gap:12px;align-items:flex-start;max-width:420px;
font-size:.83rem;color:#a1a1aa;line-height:1.55;cursor:pointer}
.fx-consent>span{flex:1 1 auto;min-width:0}
.fx-consent input[type="checkbox"]{-webkit-appearance:none;appearance:none;flex:0 0 auto;
width:20px;height:20px;margin:1px 0 0;background:#16161a;border:1.5px solid var(--akzent, #7c87ff);
border-radius:4px;cursor:pointer;position:relative;transition:background .2s ease,border-color .2s ease}
.fx-consent input[type="checkbox"]:hover{background:color-mix(in srgb,var(--akzent, #7c87ff) 14%,transparent)}
.fx-consent input[type="checkbox"]:focus-visible{outline:2px solid var(--akzent, #7c87ff);outline-offset:2px}
.fx-consent input[type="checkbox"]:checked{background:var(--akzent, #7c87ff);border-color:var(--akzent, #7c87ff)}
.fx-consent input[type="checkbox"]:checked::after{content:"";position:absolute;left:6px;top:2px;
width:5px;height:10px;border:solid #0f0f12;border-width:0 2px 2px 0;transform:rotate(45deg)}
.fx-consent a{color:var(--akzent, #7c87ff);text-decoration:underline;text-underline-offset:3px}
@media (prefers-reduced-motion:reduce){.fx-consent input[type="checkbox"]{transition:none}}
</style>
Spamschutz: Honeypot + Render-Zeit
Pol 2 · KlarheitAnlass: Formular gegen Bots
Captcha-frei: ein off-screen Honeypot-Feld (für Menschen unsichtbar, Bots füllen es aus) plus ein verstecktes Timestamp-Feld. Das JS setzt die Render-Zeit und lehnt zu schnelle Sendungen still ab. Im echten Projekt prüft der Server dieselben Werte erneut. Vorbild: Nördlicht, NDS. Live-Demo unten zeigt die Reaktion statt zu versenden.
<form class="fx-spam" aria-label="Beispiel mit Spamschutz">
<!-- Honeypot: NICHT ausfüllen — für Menschen unsichtbar -->
<div class="fx-hp" aria-hidden="true">
<label for="fx-website">Website (bitte leer lassen)</label>
<input type="text" id="fx-website" name="website" tabindex="-1" autocomplete="off">
</div>
<input type="hidden" name="rendered_at" value="">
<div class="field">
<label for="fx-email">E-Mail</label>
<input type="email" id="fx-email" placeholder="name@beispiel.de">
</div>
<button type="submit">Anfrage senden</button>
<p class="fx-spam-status" role="status" aria-live="polite"></p>
</form>
<style>
.fx-spam{display:flex;flex-direction:column;gap:12px;max-width:380px;text-align:left}
.fx-spam .field{display:flex;flex-direction:column;gap:6px}
.fx-spam label{font-size:.8rem;font-weight:600;color:#a1a1aa}
.fx-spam input{width:100%;padding:11px 14px;background:#16161a;border:1px solid #26262c;border-radius:10px;
color:#e9e9ee;font:inherit;font-size:.92rem;outline:none;transition:border-color .2s ease,box-shadow .2s ease}
.fx-spam input:focus{border-color:var(--akzent, #7c87ff);
box-shadow:0 0 0 3px color-mix(in srgb,var(--akzent, #7c87ff) 22%,transparent)}
/* Honeypot: für Menschen unsichtbar, Bots füllen es aus */
.fx-hp{position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden}
.fx-spam button{margin-top:2px;padding:11px 16px;border:1px solid var(--akzent, #7c87ff);border-radius:10px;
background:var(--akzent, #7c87ff);color:#0f0f12;font:inherit;font-weight:600;font-size:.9rem;cursor:pointer;
transition:filter .2s ease}
.fx-spam button:hover,.fx-spam button:focus-visible{filter:brightness(1.08)}
.fx-spam-status{font-size:.82rem;color:#a1a1aa;min-height:1.2em}
@media (prefers-reduced-motion:reduce){.fx-spam input,.fx-spam button{transition:none}}
</style>
<script>
document.querySelectorAll('.fx-spam').forEach(function(form){
var renderedAt=Date.now();
var ts=form.querySelector('[name="rendered_at"]'); if(ts)ts.value=String(renderedAt);
var status=form.querySelector('.fx-spam-status');
form.addEventListener('submit',function(ev){
ev.preventDefault();
var trap=form.querySelector('[name="website"]');
if(trap&&trap.value){status.textContent='Abgelehnt (Honeypot ausgefüllt).';return;}
if(Date.now()-renderedAt<1500){status.textContent='Zu schnell — vermutlich ein Bot. Abgelehnt.';return;}
// Hier würde der echte Versand an form.action erfolgen (Server prüft erneut)
status.textContent='Geprüft — bereit zum Versand.';
});
});
</script>
Formular-Status: Erfolg / Fehler inline
Pol 2 · KlarheitAnlass: Rückmeldung nach Versand
Farbcodierte Banner direkt im Formular: eine Fehlerbox bei fehlgeschlagenem Versand, eine Erfolgsbox die das Formular per .is-visible ersetzt. role="alert" bzw. role="status" für Screenreader. Vorbild: Hauszeit, NDS. Die Knöpfe schalten die Zustände nur zur Demo um.
Versand fehlgeschlagen. Bitte versuchen Sie es erneut oder rufen Sie uns an: 030 123 456.
✓
Anfrage gesendet
Vielen Dank — wir melden uns innerhalb von 24 Stunden.
<div class="fx-form-error" role="alert">
Versand fehlgeschlagen. Bitte versuchen Sie es erneut oder rufen Sie uns an:
<a href="#">030 123 456</a>.
</div>
<div class="fx-form-success" role="status">
<div class="icon" aria-hidden="true">✓</div>
<h4>Anfrage gesendet</h4>
<p>Vielen Dank — wir melden uns innerhalb von 24 Stunden.</p>
</div>
<!-- bei Erfolg: form.style.display='none'; success.classList.add('is-visible') -->
<style>
.fx-form-error{background:color-mix(in srgb,#dc2626 14%,#16161a);
border:1px solid color-mix(in srgb,#dc2626 45%,transparent);
color:#fca5a5;padding:11px 15px;border-radius:10px;font-size:.85rem;line-height:1.5}
.fx-form-error a{color:#fca5a5;font-weight:600}
.fx-form-success{display:none;text-align:center;padding:26px 18px;
background:color-mix(in srgb,var(--akzent, #7c87ff) 10%,#16161a);
border:1px solid color-mix(in srgb,var(--akzent, #7c87ff) 40%,transparent);border-radius:12px}
.fx-form-success.is-visible{display:block}
.fx-form-success .icon{font-size:2rem;color:var(--akzent, #7c87ff);line-height:1}
.fx-form-success h4{margin:.4rem 0 .2rem;color:#f4f4f5;font-size:1rem}
.fx-form-success p{margin:0;color:#a1a1aa;font-size:.85rem}
</style>
Hinweis-/Warn-Callout-Box
Pol 2 · KlarheitAnlass: Hinweis im Formular / FAQ
Getönte Box mit linker Akzentkante für wichtige Hinweise (z. B. Datenschutz, Bearbeitungsdauer). role="note" macht sie für Screenreader als Anmerkung kenntlich. Vorbild: Nördlicht.
!Hinweis: Bitte senden Sie keine sensiblen Daten (z. B. Passwörter oder Zahlungsangaben) über dieses Formular. Für vertrauliche Anliegen vereinbaren wir gern einen Rückruf.
<div class="fx-callout" role="note">
<span class="mark" aria-hidden="true">!</span>
<span><strong>Hinweis:</strong> Bitte senden Sie keine sensiblen Daten (z. B. Passwörter
oder Zahlungsangaben) über dieses Formular. Für vertrauliche Anliegen vereinbaren wir
gern einen Rückruf.</span>
</div>
<style>
.fx-callout{max-width:480px;display:flex;gap:12px;align-items:flex-start;
background:color-mix(in srgb,var(--akzent, #7c87ff) 8%,#16161a);
border:1px solid color-mix(in srgb,var(--akzent, #7c87ff) 22%,transparent);
border-left:4px solid var(--akzent, #7c87ff);border-radius:10px;padding:14px 16px;
font-size:.84rem;line-height:1.55;color:#c9c9d2}
.fx-callout .mark{flex:0 0 auto;color:var(--akzent, #7c87ff);font-weight:700}
.fx-callout strong{color:#f4f4f5}
</style>
Mehrstufiger Wizard mit Fortschrittsbalken
Pol 1 · CraftAnlass: geführte Anfrage / Konfigurator
Mehrschritt-Formular: Schritte per .is-active, animierter Progress-Fill, Radio-Optionen als ganze klickbare Karten via :has(input:checked). Kleines JS für Schrittwechsel. Vorbild: NDS. Kompakt auf drei Schritte reduziert.
Pol 2 · KlarheitAnlass: Upload / Ladezustand, Wizard-Fortschritt
Zwei Varianten: ein determinierter Balken, dessen Füllung sich weich auf einen Zielwert schiebt (hier 68 %), und ein indeterminater Balken mit endlos laufendem Streifen für unbekannte Dauer. role="progressbar" mit aria-valuenow/min/max. Kleines JS setzt beim Laden die Zielbreite. Vorbild: animate-ui „Progress".
Pol 2 · KlarheitAnlass: Einstellungen, Consent-Optionen
Echter <input type="checkbox">, visuell versteckt per sr-only-Technik (nicht display:none — bleibt fokussierbar). Der Knopf gleitet, die Bahn färbt sich bei :checked in der Akzentfarbe. Label klickbar, per Leertaste schaltbar, eigener Fokus-Ring am Schalter. Reines CSS ohne JS. Vorbild: animate-ui „Switch".
Pol 2 · KlarheitAnlass: Formular-Zustimmung, Auswahllisten
Echte Checkbox (sr-only versteckt), beim Anhaken zeichnet sich das Häkchen per stroke-dasharray/stroke-dashoffset als Inline-SVG, die Box füllt sich in der Akzentfarbe. Label klickbar, eigener Fokus-Ring. Bei reduced-motion erscheint das Häkchen sofort ohne Zeichnen. Vorbild: animate-ui „Checkbox".
Das Label sitzt zunächst als Platzhalter im Feld und wandert bei Fokus oder Eingabe nach oben — reines CSS über :not(:placeholder-shown), kein JS. Das echte <label> bleibt sichtbar (BFSG), das placeholder=" " ist nur der Schalter. Vorbild: Material-Textfeld.
Pol 1 · CraftAnlass: Registrierung / Passwort setzen
Vier Segment-Balken färben sich live nach geschätzter Stärke (Länge, Groß-/Kleinbuchstaben, Ziffern, Sonderzeichen), begleitet von einer Textstufe. Der Augen-Knopf schaltet die Sichtbarkeit per aria-pressed um. Rein clientseitige Orientierung, keine Sicherheitsprüfung. Vorbild: gängige Sign-up-Felder.
Gestrichelte Fläche zum Klicken oder Hineinziehen von Dateien; ein echtes <input type="file"> bleibt per sr-only-Technik fokussierbar (BFSG). Beim Überfahren hebt sich der Rand hervor, gewählte Dateien erscheinen als Liste mit Namen und Größe. Kein Versand — nur Auswahl-Anzeige.
Sechs Einzelfelder für einen numerischen Code: Eingabe springt automatisch weiter, Backspace zurück, Einfügen eines kompletten Codes verteilt die Ziffern. inputmode="numeric" öffnet mobil die Zahlentastatur, autocomplete="one-time-code" erlaubt Auto-Ausfüllen. Vorbild: SMS-/App-Code-Eingabe.
Nativer <input type="range"> mit eigener Optik: die gefüllte Spur wächst per background-size, der aktuelle Wert steht live in einem <output>. Funktioniert per Tastatur out of the box, Firefox nutzt ::-moz-range-progress. Ein winziges JS spiegelt den Wert.