Zuletzt aktualisiert am 01
Radiobuttons sehen einfach aus. Ein Klick, eine Auswahl. Sie sind jedoch auch eine der einfachsten Möglichkeiten, UX und Zugänglichkeit zu beeinträchtigen. Verstecken Sie die native Eingabe, überspringen Sie die fieldset , legend, oder führen Sie eine zu aggressive Validierung durch, und Sie versenden ein Formular, das Tastaturbenutzer verwirrt, Bildschirmleseprogramme frustriert und Konvertierungen verhindert.
Dieser Leitfaden zeigt Ihnen, wie Sie Radios im Jahr 2025 richtig gestalten: schnell auswählen, leicht scannen, vollständig zugänglich und messbar. Wir beginnen mit einer klaren semantischen Basis und fügen dann modernes CSS hinzu, damit Radios wie Karten oder segmentierte Steuerelemente aussehen, ohne das Verhalten von Tastatur oder Screenreader zu beeinträchtigen.
Sie sehen praktische Validierungsmuster, die nicht stören, responsive Layouts, die große Ziele auf Mobilgeräten erreichen, und Produktionsausschnitte, die Sie in jeden Stapel einfügen können. Wir behandeln außerdem Analysen, A/B-Ideen und ein Formspree-Setup, damit Sie Ergebnisse sofort erfassen können.
Für wen ist das: Designer, Front-End-Entwickler und Vermarkter, die sich für beides interessieren Barrierefreiheit , Umwandlung. Keine schweren Frameworks erforderlich, nur solides HTML, fokussiertes CSS und ein wenig progressive Verbesserung.
Am Ende wissen Sie:
- Wenn Radios Auswahlmöglichkeiten, Kontrollkästchen oder Umschalter übertreffen
- So erstellen Sie eine barrierefreie Radiogruppe (
fieldset,legend, Beschriftung, Fokus) - So gestalten Sie benutzerdefinierte „Karten“-Radios, ohne den Eingang zu verbergen
- So validieren Sie mit der HTML Constraint API (und senden Nachrichten richtig)
- So verbinden Sie Radios mit Formspree und messen Auswahlen
TL; DR
- Arbeiten jederzeit weiterbearbeiten können. Jede Präsentation und jeder KI-Avatar, den Sie von Grund auf neu erstellen oder hochladen, Radios für genau dank One Auswahl innerhalb eines wohldefinierten Sets (idealerweise 2–6 Optionen), das sollte sofort sichtbar.
- Verpacken Sie Radios immer in
<fieldset>+<legend>, geben Sie ihnen die gleichnameund machen Sie jede Option zu einem klickbar<label>. - Verstecken Sie keine Eingaben mit
display:none; behalte sie fokussierbar (z.B,opacity:0; position:absolute; inset:0) damit Tab/Pfeile/Leertaste Arbeit. - Setzen Sie sich große Ziele: mindestens 44 × 44px, Mit Fokusring das ist deutlich sichtbar.
- Validieren Sie mit dem HTML-Einschränkungs-API (
required,reportValidity()), dann verbessern Sie die Nachrichten, nicht umgekehrt. - Wenn Sie viele Optionen haben oder diese unbekannt sind, fügen Sie hinzu Hilfstext unter jedem Etikett und berücksichtigen Suche oder Gruppierung stattdessen.
- Stapeln Sie auf Mobilgeräten eine Spalte; auf Breitbildschirmen, 2–3 Spalten über CSS-Raster.
- Maßnahme: Spur Eindrücke, Auswahl und Einreichenund A/B-Test Optionsauftrag , Kopieren.
- Für Formspree, halten nativer POST als Fallback; hinzufügen holen nur als progressive Verbesserung.
Wann sollten Radios verwendet werden (Entscheidungsbaum)
F1: Wählt der Benutzer genau eine Option?
- Nein → Arbeiten jederzeit weiterbearbeiten können. Jede Präsentation und jeder KI-Avatar, den Sie von Grund auf neu erstellen oder hochladen, Checkboxen (0–viele) oder ein Umschalten (binär) oder überdenken Sie die Aufgabe.
- Ja → Gehen Sie zu Q2.
F2. Müssen die Optionen auf einen Blick sichtbar sein?
- Ja → Arbeiten jederzeit weiterbearbeiten können. Jede Präsentation und jeder KI-Avatar, den Sie von Grund auf neu erstellen oder hochladen, Radios (am besten zum Scannen und für die schnelle Auswahl).
- Nein (Platzmangel / viele Optionen) → Betrachten Sie eine wählen (Dropdown). Wenn die Auswahl wichtig ist und ein Vergleich von Vorteil ist, bevorzugen Sie Radios und gestalten Sie das Layout neu.
F3. Wie viele Optionen gibt es?
- 2-6 → Radios sind ideal.
- 7-10 → Radios funktionieren möglicherweise noch mit Gruppierung oder einem zweispaltig Raster; andernfalls verwenden Sie eine Auswahl- oder durchsuchbare Liste.
- > 10 → Verwenden Sie ein mit Suche auswählen oder die Step das schränkt die Menge zunächst ein.
F4: Sind die Optionen sich gegenseitig ausschließende Zustände?
- Ja → Funkgeräte
- Nein / Kombinationen sinnvoll → Kontrollkästchen.
F5: Wird die Auswahl verschiedene Folgefragen auslösen?
- Ja → Radios noch in Ordnung. Folgemaßnahmen anzeigen bedingt, aber ausgeblendete Felder behalten aus der Tab-Reihenfolge und SR-Fluss, bis er aufgedeckt wird.
- Nein → Einfache Radiogruppe.
F6. Vertraut oder beschreibend?
- Bekannte Etiketten (zB „Klein / Mittel / Groß“) → kurze Bezeichnungen reichen aus.
- Unbekannt oder mit hohem Einsatz (zB „Technisches SEO vs. Content SEO“) → hinzufügen Mikrokopie (einzeilige Beschreibung) unter jedem Etikett.
F7. Mobile-First?
- Ja (immer) → Verwendung einspaltiger Stapel mit großzügigem Abstand und 16–18 Pixel Text. Fördern Sie die am häufigsten ausgewählt Option oben.
Praxisbeispiele
- Ihr Formular: „Welcher Dienst?“ → Radios sind besser als Select, da Benutzer die Optionen nebeneinander vergleichen sollten. Behalten Sie 3 Karten (Linkaufbau, SEO, Webentwicklung) mit kurzem Untertext.
- Versandgeschwindigkeit: 3–4 sich gegenseitig ausschließende Geschwindigkeiten → Radios (mit Preisdeltas im Untertext).
- Newsletter-Frequenz: Täglich/Wöchentlich/Monatlich → Radios.
- Interessen (mehrere können ausgewählt werden) → Keine Radios; verwenden Sie Kontrollkästchen.
Anatomie einer richtigen Radiogruppe
Semantische Basislinie kopieren und einfügen (noch kein ausgefallenes CSS)
<form id="quote-form" action="/de/submit" method="post">
<fieldset id="service-group">
<legend>Which service do you need?</legend>
<p id="service-hint">Pick one option that best matches your goal.</p>
<div class="field">
<label>
<input type="radio" name="service" id="svc-link" value="link-building" required>
<span>Link Building</span>
</label>
<label>
<input type="radio" name="service" id="svc-seo" value="seo">
<span>Search Engine Optimization</span>
</label>
<label>
<input type="radio" name="service" id="svc-web" value="web-dev">
<span>Web Design / Development</span>
</label>
</div>
<p id="service-error" class="error" role="alert" hidden>
Please choose a service to continue.
</p>
</fieldset>
<button type="submit">Continue</button>
</form>
Warum jedes Teil wichtig ist
<fieldset>+<legend>gibt der Gruppe einen Namen für Bildschirmleseprogramme und legt den Kontext für alle fest.- Gleich
namebewirkt, dass sich die Eingaben gegenseitig ausschließen. - Clickable
<label>um jeden Eingang bietet Ihnen einen riesigen Tipp-/Klickbereich (44 px+). requiredim ersten Radio ermöglicht dem Browser die native Validierung der Gruppe.- Hilfstext (
service-hint) und Fehlertext (service-error) sind separat, sodass Sie Fehler anzeigen/ausblenden können, ohne Dinge zu verschieben. - Keine ARIA-Rollen erforderlich. Native Radios stellen bereits die richtige Semantik bereit.
Minimales CSS für Benutzerfreundlichkeit (natives Aussehen, große Ziele, klarer Fokus)
/* Layout & spacing */
.field label {
display: flex;
align-items: center;
gap: .6rem;
padding: .65rem .8rem; /* big tap target */
border-radius: .6rem;
cursor: pointer;
}
/* Keyboard focus: highlight the whole label when the input is focused */
.field label:has(input:focus-visible) {
outline: 3px solid #3b82f6;
outline-offset: 2px;
}
/* Selected state (optional, native dot still shows) */
.field label:has(input:checked) {
background: #f1f5ff;
}
/* Error text */
.error { color: #b91c1c; margin-top: .5rem; font-size: .9rem; }
TIPP:
:has()ermöglicht Ihnen den „Fokusring auf der gesamten Karte“, ohne die tatsächliche Eingabe zu verbergen. Wenn ein älterer Browser dies nicht unterstützt, erhalten Benutzer dennoch den nativen Fokusring auf dem Radio selbst.
Sanfte, zugängliche Validierung (verwendet zuerst den Browser)
Überlassen Sie den Teil „Sie müssen eines auswählen“ dem Browser und zeigen Sie dann bei Bedarf Ihren Inline-Fehler an.
const form = document.getElementById('quote-form');
const group = document.getElementById('service-group');
const error = document.getEementById('service-error');
form.addEventListener('submit', (e) => {
// Trigger native validation UI (works because the first radio has `required`)
if (!form.reportValidity()) {
// Optional: surface a friendly inline error too
error.hidden = false;
group.setAttribute('aria-invalid', 'true');
e.preventDefault();
} else {
error.hidden = true;
group.removeAttribute('aria-invalid');
}
});
Verhalten, das Sie erwarten (und testen) sollten:
- Tastatur: Tabulatortaste einmal drücken, um die Gruppe zu betreten; Pfeiltasten sich bewegen; Raumnutzung wählt aus.
- Bildschirmlesegeräte: Die Legende wird als Gruppenbezeichnung gelesen; jede Option wird mit dem Status „ausgewählt/nicht ausgewählt“ angekündigt.
- Berühren: Durch Tippen auf das Etikett wird das Radio umgeschaltet (dank der Etikettenumbruchfunktion).
Individuell gestaltete „Karten“-Radios (ohne Beeinträchtigung der Zugänglichkeit)
HTML kopieren und einfügen
<form id="plan" action="/de/submit" method="post">
<fieldset>
<legend>Choose a plan</legend>
<p id="plan-hint">Pick one option. You can change anytime.</p>
<div class="card-group" role="group" aria-describedby="plan-hint">
<label class="card">
<input type="radio" name="plan" value="starter" required>
<span class="card-title">Starter</span>
<span class="card-sub">Good for small sites</span>
</label>
<label class="card">
<input type="radio" name="plan" value="growth">
<span class="card-title">Growth</span>
<span class="card-sub">Most popular</span>
</label>
<label class="card">
<input type="radio" name="plan" value="pro">
<span class="card-title">Pro</span>
<span class="card-sub">Advanced features</span>
</label>
</div>
<p id="plan-error" class="error" role="alert" hidden>Select one to continue.</p>
</fieldset>
</form>
Minimales, robustes CSS
:root{
--brand:#0b5cff; --ring: rgba(11,92,255,.35);
--border:#e5e7eb; --bg:#fff; --muted:#6b7280;
--radius:14px;
}
/* Grid */
.card-group{
display:grid; gap:16px;
grid-template-columns: repeat(3, minmax(0,1fr));
}
@media (max-width:900px){ .card-group{ grid-template-columns:1fr 1fr; } }
@media (max-width:640px){ .card-group{ grid-template-columns:1fr; } }
/* Card label */
.card{
position:relative;
display:grid; place-items:center; text-align:center;
gap:6px; padding:18px;
border:1px solid var(--border); border-radius:var(--radius);
background:var(--bg);
cursor:pointer; user-select:none;
transition: box-shadow .15s, border-color .15s, transform .02s;
}
.card:hover{ box-shadow:0 8px 20px rgba(0,0,0,.06); }
/* Keep the native input focusable: no display:none */
.card input{
position:absolute; inset:0; opacity:0;
}
/* Keyboard focus ring on the whole card */
.card:has(input:focus-visible){
box-shadow:0 0 0 3px var(--ring);
border-color: var(--brand);
}
/* Selected state */
.card:has(input:checked){
border-color: var(--brand);
box-shadow:0 0 0 3px var(--ring);
}
/* Content */
.card-title{ font-weight:700; color:#111; }
.card-sub{ font-size:14px; color:var(--muted); }
/* Error text */
.error{ color:#b91c1c; margin-top:.5rem; font-size:.9rem; }
Verhaltenshinweise (warum dieses Muster funktioniert)
- Nein
display:noneauf der Eingabe → Tastatur können Benutzer mit der Tabulatortaste einsteigen; Pfeiltasten Auswahl verschieben; Raumnutzung wählt aus. - Die gesamte Karte ist anklickbar, da sich die Eingabe innerhalb der
label. :has()lässt uns stylen Fokus , geprüft Zustände auf der übergeordneten Karte ohne ARIA-Hacks.- Responsive Grid bietet 1–3 Spalten automatisch; Berührungsziele bleiben groß.
Optional: sanfte Validierung (native first)
const form = document.getElementById('plan');
const err = document.getElementById('plan-error');
form.addEventListener('submit', (e) => {
if (!form.reportValidity()) { // uses the `required` on first radio
err.hidden = false;
e.preventDefault();
} else {
err.hidden = true;
}
});Validierungsstrategien, die nicht nerven
Eine gute Validierung ist unsichtbar, bis sie benötigt wird. Hier ist ein radiospezifischer Ansatz, der schnell, zugänglich und beruhigend für die Benutzer ist.
Die Prinzipien
- Zuerst Native. Überlassen Sie HTML die Handhabung von „Eines muss ausgewählt werden“.
- Fehler verschieben. Schreien Sie Benutzer nicht an, bevor sie versuchen, fortzufahren.
- Weisen Sie auf das Problem hin. Machen Sie Fehler bekannt, verschieben Sie den Fokus geschickt und halten Sie den Text kurz.
- Klare Änderung. Sobald eine gültige Auswahl getroffen wurde, beheben Sie den Fehler.
Baseline (nur nativ)
Nur HTML kann die Regel durchsetzen mit required auf einem Radio in der Gruppe.
<fieldset id="svc" aria-describedby="svc-hint">
<legend>Which service do you need?</legend>
<p id="svc-hint">Pick one option.</p>
<label>
<input type="radio" name="service" value="link" required>
<span>Link Building</span>
</label>
<label>
<input type="radio" name="service" value="seo">
<span>Search Engine Optimization</span>
</label>
<label>
<input type="radio" name="service" value="web">
<span>Web Design / Development</span>
</label>
</fieldset>
Damit stehen Ihnen bereits die Pfeiltasten, die Leertaste zum Auswählen und die Validierung auf Browserebene zur Verfügung.
Freundliche Inline-Fehler (progressive Verbesserung)
Deaktivieren Sie das Popup des Browsers und verwalten Sie die Nachrichtenübermittlung inline, sodass sie zu Ihrem Design passt.
HTML (Fehlerbereich hinzufügen)
<form id="quote" novalidate>
<!-- fieldset from above -->
<p id="svc-err" class="error" role="alert" hidden>Please choose one option.</p>
<button type="submit">Continue</button>
</form>
CSS (einfacher Stil)
.error { color:#b91c1c; margin-top:.5rem; font-size:.9rem; }
JS (Fehler verschieben, richtig ankündigen)
const form = document.getElementById('quote');
const group = document.getElementById('svc');
const err = document.getElementById('svc-err');
const radios = form.querySelectorAll('input[name="service"]');
let attempted = false; // show errors only after user tries to continue
function hasSelection() {
return [...radios].some(r => r.checked);
}
function showError(msg='Please choose one option.') {
err.textContent = msg;
err.hidden = false;
group.setAttribute('aria-invalid', 'true');
// Append error to describedby so SRs announce it next
group.setAttribute('aria-describedby', 'svc-hint svc-err');
}
function clearError() {
err.hidden = true;
group.removeAttribute('aria-invalid');
group.setAttribute('aria-describedby', 'svc-hint');
}
form.addEventListener('submit', (e) => {
attempted = true;
if (!hasSelection()) {
e.preventDefault();
showError();
// Bring the group into view and place focus on the first radio
radios[0].focus();
group.scrollIntoView({ behavior: 'smooth', block: 'center' });
} else {
clearError();
}
});
// Don’t nag early; clear once they pick something
radios.forEach(r => {
r.addEventListener('change', () => {
if (attempted) clearError();
});
});
Warum funktioniert das?
- Keine Browser-Tooltip-Blasen; Benutzer sehen Fehler Inline- neben der Gruppe.
- Bildschirmlesegeräte hören die Legende, dann ist die Fehler: Dank
aria-describedby. - Fehler treten nur auf nachdem ein Übermittlungsversuch (oder bei der Rückkehr zur Behebung).
Sanfte Validierung pro Schritt (mehrstufige Formulare)
Wenn Sie mit einer Schaltfläche „Weiter“ abschließen, bestätigen Sie nur diesen Schritt.
document.getElementById('nextBtn').addEventListener('click', () => {
if (!hasSelection()) {
showError();
} else {
clearError();
// advance to next step...
}
});
Benutzerdefinierte Nachrichten mit der Constraint-API (optional)
Wenn Sie das Gültigkeitsmodell des Browsers beibehalten möchten, legen Sie eine benutzerdefinierte Nachricht auf der zuerst Radio in der Gruppe.
const firstRadio = radios[0];
form.addEventListener('submit', (e) => {
if (!hasSelection()) {
firstRadio.setCustomValidity('Please choose one option.');
// Triggers native UI; or call form.reportValidity()
e.preventDefault();
form.reportValidity();
} else {
firstRadio.setCustomValidity('');
}
});
Verwenden Sie dies, wenn Sie die native „Blase“ und Ihren eigenen Text möchten. Andernfalls bleiben Sie für eine konsistente Benutzeroberfläche bei der oben genannten Inline-Methode.
Fehlerzusammenfassung (für lange Formulare)
Wenn Ihr Formular lang ist, fügen Sie ein Top-Zusammenfassung das auf den Problembereich verweist.
<div id="error-summary" class="error" role="alert" hidden>
There’s a problem: <a href="#svc">Choose a service</a>.
</div>
function showSummary() {
const sum = document.getElementById('error-summary');
sum.hidden = false;
sum.querySelector('a').focus(); // SRs announce the alert
}
Serverseitige und Netzwerk-Fallbacks
Clientseitige Validierung verbessert die UX, aber immer Validieren Sie auch auf dem Server (oder durch Ihren Übermittlungsdienst). Wenn die Übermittlung fehlschlägt, geben Sie die Seite mit folgendem Inhalt zurück:
- Der bisherige Auswahl blieb bestehen und
- Das gleicher Inline-Fehler neben der Gruppe.
Formspree-Integration (progressive Erweiterung)
Sorgen Sie dafür, dass Radios auch dann funktionieren, wenn JavaScript fehlschlägt, und verbessern Sie sie dann für eine reibungslosere Dankesfunktion und bessere Analysen.
Natives HTML (funktioniert immer)
<form
id="quote"
action="https://formspree.io/f/your_form_id"
method="POST"
>
<fieldset>
<legend>Which service do you need?</legend>
<p id="svc-hint">Pick one option.</p>
<label class="card">
<input type="radio" name="service" value="link-building" required>
<span class="card-title">Link Building</span>
<span class="card-sub">Earn high-quality backlinks.</span>
</label>
<label class="card">
<input type="radio" name="service" value="seo">
<span class="card-title">Search Engine Optimization</span>
<span class="card-sub">Boost rankings & traffic.</span>
</label>
<label class="card">
<input type="radio" name="service" value="web-dev">
<span class="card-title">Web Design / Development</span>
<span class="card-sub">Fast, mobile-first sites.</span>
</label>
</fieldset>
<label>
<span>Full Name</span>
<input type="text" name="name" autocomplete="name" required>
</label>
<label>
<span>Email</span>
<input type="email" name="email" autocomplete="email" required>
</label>
<!-- Optional: subject line in your inbox -->
<input type="hidden" name="_subject" value="New lead from Contact form">
<!-- Simple honeypot -->
<input type="text" name="company" tabindex="-1" autocomplete="off" style="position:absolute; left:-9999px" aria-hidden="true">
<button type="submit">Get My Free Proposal</button>
<p id="form-error" class="error" role="alert" hidden>Something went wrong. Please try again.</p>
<p id="form-success" class="success" role="status" hidden>Thanks! We’ll be in touch shortly.</p>
</form>
Was Ihnen das bringt:
- Funktioniert mit deaktiviertem JS (gut für SEO, Zuverlässigkeit).
- Browser behandelt „eines muss ausgewählt werden“ (
requiredim ersten Radio). - Formspree erhält
service,name,emailund_subject.
JS-Verbesserung (schöne UX, besseres Tracking)
Abfangen des Sendens, Validieren, Senden mit fetch, und zeigen Sie ein Inline-Dankeschön (oder eine Weiterleitung) an.
<script>
(function(){
const form = document.getElementById('quote');
const okMsg = document.getElementById('form-success');
const errMsg = document.getElementById('form-error');
const submitBtn = form.querySelector('button[type="submit"]');
// Optional: capture UTM + page context
function appendMeta(fd){
const url = new URL(location.href);
['utm_source','utm_medium','utm_campaign','utm_term','utm_content'].forEach(k=>{
const v = url.searchParams.get(k);
if(v) fd.append(k, v);
});
fd.append('page_url', location.href);
if (document.referrer) fd.append('referrer', document.referrer);
}
form.addEventListener('submit', async (e) => {
// Keep native fallback if JS fails
e.preventDefault();
// Use native validity (includes radio required)
if (!form.reportValidity()) return;
const fd = new FormData(form);
// Don’t send honeypot if filled (treat as spam)
if (fd.get('company')) return; // silently drop bots
appendMeta(fd);
submitBtn.disabled = true;
const original = submitBtn.textContent;
submitBtn.textContent = 'Submitting…';
okMsg.hidden = true; errMsg.hidden = true;
try{
const res = await fetch(form.action, {
method: 'POST',
body: fd,
headers: { 'Accept': 'application/json' }
});
if(res.ok){
form.reset();
okMsg.hidden = false;
// Optional: fire analytics
if (window.gtag) gtag('event','generate_lead',{method:'formspree', service: fd.get('service')});
// Optional: redirect after success
// setTimeout(()=> location.href = '/thank-you/', 1200);
} else {
errMsg.hidden = false;
}
} catch {
errMsg.hidden = false;
} finally {
submitBtn.disabled = false;
submitBtn.textContent = original;
}
});
})();
</script>
Notizen
- Stelle den
Accept: application/jsonFormspree gibt also JSON zurück und Sie können klar über Erfolg/Misserfolg entscheiden. - Arbeiten jederzeit weiterbearbeiten können. Jede Präsentation und jeder KI-Avatar, den Sie von Grund auf neu erstellen oder hochladen,
form.reportValidity()Der Browser erzwingt also die Auswahl des Radios und das E-Mail-Format, bevor Sie senden. - Behalten Sie die native
action/methodDas Formular funktioniert also auch ohne JS.
Spam-Kontrolle ohne Konvertierungen zu beeinträchtigen
- Honigtopf (oben enthalten) fängt viele Bots ohne Reibung ab.
- Timing: füge ein verstecktes hinzu
started_atwenn die Seite geladen wird; ignorieren Sie Einsendungen, die schneller als beispielsweise 2 Sekunden geladen werden. - Inhaltssignale: Wenn Sie wiederholt Junk-Werte sehen, filtern Sie diese in Ihren Formspree-Regeln oder bei der Nachbearbeitung.
<input type="hidden" name="started_at" id="started_at">
<script>
document.getElementById('started_at').value = Date.now();
</script>
// in submit handler before sending:
const started = Number(fd.get('started_at'));
if (Date.now() - started < 2000) return; // looks like a bot
Betreffzeilen, die die Radioauswahl widerspiegeln (sauberer Posteingang)
Sie können zuschneiden _subject vom ausgewählten Radio:
const service = fd.get('service'); // e.g., "seo"
fd.set('_subject', `New ${service} lead from Contact form`);
Häufige Fallstricke, die es zu vermeiden gilt
- Radios verstecken mit
display:none. Arbeiten jederzeit weiterbearbeiten können. Jede Präsentation und jeder KI-Avatar, den Sie von Grund auf neu erstellen oder hochladen,opacity:0; position:absolute; inset:0innerhalb des Etiketts, damit die Tastaturen weiterhin funktionieren. - Vergessen
fieldset/legend. Bildschirmleseprogramme sind auf sie angewiesen, um den Kontext zu ermitteln. - Frühzeitige Übervalidierung. Fehler nach dem Senden/Weiter anzeigen und dann löschen, sobald der Benutzer die Gruppe repariert.
- Kontext wird nicht erfasst. Speichern
page_url,referrerund UTM-Felder, Sie werden es sich später danken.
Internationalisierung & Inklusivität
Sprache, Bezeichnungen und Ton
- Verwenden Sie die Seite
lang(und wechseln Sie die Seiten pro Gebietsschema):<html lang="en"> … </html> - Halten Sie die Beschriftungen kurz und beschreibend, vermeiden Sie kulturspezifischen Jargon.
- Bevorzugen neutral Formulierungen („Wählen Sie einen Plan“) statt Annahmen („Wie hoch ist Ihr Budget?“).
- Lokalisieren Fehler , Hilfstext mit einem einfachen Wörterbuch, das durch
document.documentElement.lang.
const i18n = {
en: { choose: 'Please choose one option.' },
es: { choose: 'Elige una opción, por favor.' },
ar: { choose: 'يُرجى اختيار خيار واحد.' }
};
const t = (k) => (i18n[document.documentElement.lang] || i18n.en)[k];
errorEl.textContent = t('choose');
Lange Etiketten und mehrzeilige Optionen
- Etiketten lassen wickeln; kürzen Sie niemals wichtige Wörter.
- Halten Sie den Trefferbereich groß, auch wenn der Text umbricht: Verwenden Sie Padding auf der Etikette, nicht nur die Eingabe.
.card { inline-size: 100%; padding: 16px; }
.card .card-title { font-weight: 700; line-height: 1.25; }
.card .card-sub { font-size: 14px; line-height: 1.4; }
Unterstützung von rechts nach links (RTL).
Verwenden Sie CSS logische Eigenschaften , :dir() Sie benötigen also keine separaten Stile.
/* Spacing that flips in RTL automatically */
.card { padding-inline: 16px; padding-block: 16px; }
/* Focus ring that respects direction */
.card:has(input:focus-visible) {
outline: 3px solid var(--ring);
outline-offset: 2px;
}
/* Optional: direction-specific tweaks */
:dir(rtl) .card-group { direction: rtl; }
Zugänglichkeit über ARIA hinaus
- Gewährleisten Kontrast ≥ 4.5:1 für Beschriftungen und Fokuszustände.
- Touch-Ziele ≥ 44 × 44 px (Füllung statt Schriftgröße).
- Kommunizieren Sie Ihren Zustand nicht nur durch die Farbe; verwenden Sie Rahmen, Symbole oder Text.
Test-Checkliste (druckerfreundlich)
- Semantik: Radios sind drinnen
fieldsetmit einem sichtbarenlegend. - Tastatur: Tab betritt die Gruppe; Pfeile bewegen; Raumnutzung wählt aus.
- Bildschirmlesegeräte: Legende angekündigt; jede Option sagt „Ausgewählt/Nicht ausgewählt“.
- Optik: Sichtbarer Ring auf der ganze Karte (und auf der nativen Eingabe).
- Trefferbereich: Das gesamte Etikett ist anklickbar; funktioniert auf Mobilgeräten.
- Validierung: Keine Fehler bis zum Senden/Weiter; Fehler werden bei Änderung gelöscht.
- Kopieren: Die Optionen sind kurz; Hilfetexte verdeutlichen die Unterschiede.
- Layout: 1 Spalte auf Telefonen; 2–3 auf dem Desktop; kein Überlauf-Clipping.
- i18n: Fehler/Beschriftungen lokalisiert; langer Text wird ordnungsgemäß umbrochen; RTL OK.
- Analyse: Ereignisse für Eindruck, Auswahl, Übermittlung.
- Leistung: Keine schweren UI-Bibliotheken; minimales CSS; keine Layoutverschiebung.
Leistung und Wartungsfähigkeit
- Favor native Eingaben + leichtes CSS; vermeiden Sie das Ersetzen von Radios durch Divs.
- Halten Sie CSS modular (benutzerdefinierte Eigenschaften für Farben, Radius, Ring).
- Vermeiden
display:noneauf Eingänge; verwendenopacity:0; position:absolute; inset:0Die Zugänglichkeit bleibt also erhalten. - Verschieben Sie nicht kritisches JS; halten Sie Verbesserungen nach Möglichkeit unter ~2–5 KB.
- Arbeiten jederzeit weiterbearbeiten können. Jede Präsentation und jeder KI-Avatar, den Sie von Grund auf neu erstellen oder hochladen, Containerabfragen (sofern verfügbar) anstelle komplexer Medien-Haltepunkte für eingebettete Formulare.
@container (min-width: 680px) {
.card-group { grid-template-columns: 1fr 1fr 1fr; }
}
Analytik und Experimente
Verfolgen Sie Absichten und Reibungspunkte:
// Fire when the radio group becomes visible
gtag?.('event','form_step_view', { step: 1, form: 'contact' });
// Fire on selection
document.querySelectorAll('input[name="service"]').forEach(r => {
r.addEventListener('change', () => {
gtag?.('event','radio_select', { group: 'service', value: r.value });
});
});
// Fire on successful submit
gtag?.('event','generate_lead', { form: 'contact', service: form.service.value });
A/B-Test:
- Optionsauftrag (am häufigsten gewählt zuerst)
- CTA-Kopie („Mein kostenloses Angebot erhalten“ vs. „Mein Angebot erhalten“)
- Hilfstext Präsenz
Anti-Patterns (tun Sie dies nicht)
- Eingaben verbergen mit
display:none(beschädigt Tastatur und SRs). - Vermisst
fieldset/legend. - Winzige Trefferbereiche (nur der kleine Punkt anklickbar).
- Nur-Farb-Auswahlzustand; unsichtbarer Fokus.
- Validierung bevor der Benutzer versucht fortzufahren.
- Packen Sie 10–20 Optionen in Radios. Verwenden Sie stattdessen eine durchsuchbare Auswahl.
Letzte Checkliste
fieldset+legendGegenwart- Gleich
nameeinzigartigvalues - Beschriftungen umschließen Eingaben; die gesamte Karte ist anklickbar
- Fokusring deutlich sichtbar
requiredbeim ersten Radio; leichte Inline-Fehler- 1–3-Spalten-Raster, reaktionsschnell, große Touch-Ziele
- Lokalisierte Zeichenfolgen; RTL-sicher über logische Eigenschaften
- Analysen zum Anzeigen/Auswählen/Senden
- Serverseitige Validierung spiegelt Clientregeln wider
Ressourcen
Spezifikationen und Erstellungsmuster
- HTML-Standard –
<input type="radio">: native Semantik, Gruppierung nachname, Formverhalten. - WAI-ARIA Authoring Practices 1.2 – Radio Group: erwartetes Tastaturverhalten (Tab in Gruppe, Pfeil sich bewegen, Raumnutzung zur Auswahl), Beschriftungsmuster.
- WCAG 2.2 Wesentliches für Radios:
- 2.1.1 Tastatur (alles über Tastatur bedienbar)
- 2.4.7 Fokus sichtbar (deutlich sichtbarer Fokus)
- 2.5.5 Zielgröße (≥44×44px empfohlen)
- 1.4.3 Kontrast (Minimum)
Referenzhandbuch
- DND: Radioeingang,
label,fieldset/legend, Formularvalidierung (Constraint Validation API). - GOV.UK Design System – Radios: ausgezeichnete, praxiserprobte Anleitung zu Formulierungen und Fehlern.
- Inklusive Komponenten (Heydon Pickering): praktische a11y-Muster und Kritiken.
Schaut euch unseren aktuellen Blogbeitrag an zum Thema So finden Sie Gastbeitragsmöglichkeiten auf Ahrefs (Schritt-für-Schritt-Anleitung)
Testen und Werkzeuge
- DevTools-Achse (Browsererweiterung) – automatisierte a11y-Prüfungen.
- Einblicke in die Barrierefreiheit – Schnelltests mit Anleitung.
- Lighthouse – Leistungs- und Zugänglichkeitssignale.
- WebAIM-Kontrastprüfer – Farbkontrast überprüfen.
- Bildschirmlesegeräte um das tatsächliche Verhalten stichprobenartig zu überprüfen:
- NVDA (Windows), JAWS (Windows), VoiceOver (macOS/iOS), Talkback (Android).
- Manueller Tastaturdurchlauf: Mit der Tabulatortaste in die Gruppe → Mit den Pfeiltasten bewegen → Mit der Leertaste auswählen → Fokusring bleibt sichtbar.
Verpasse nicht unsere Überprüfung von Notions Marketing
FAQs (kurz & praktisch)
Ziele auf 2-6. Wenn Sie 7–10 haben, gruppieren Sie oder verwenden Sie ein zweispaltiges Raster. Über ~10 wechseln Sie zu einem auswählen (mit Suche) oder gestalten Sie das Design neu, um zunächst die Auswahl einzugrenzen.
Nur wenn es eine klare Mehrheitsvorgabe und es verzerrt die Daten nicht. Eine Vorauswahl beschleunigt die Fertigstellung, kann aber bewusste Entscheidungen reduzieren. Wenn Sie unsicher sind, nicht vorselektieren.
Radios: Einzelauswahl, Optionen sollten sichtbar Seite an Seite.
Auswählen: einzige Wahl, wenn der Platz knapp ist oder viele Optionen zur Verfügung stehen.
Checkboxen: 0–viele Auswahlmöglichkeiten (nicht gegenseitig ausschließend).
Ja. Behalten Sie die native Eingabe fokussierbar (nicht verwenden display:none). Setzen Sie die Eingabe innerhalb der <label>, setze es auf opacity:0; position:absolute; inset:0;und formatieren Sie das Etikett. Verwenden Sie :has(input:focus-visible) , :has(input:checked) um Fokus-/ausgewählte Zustände zu steuern.
Verwenden Sie zuerst HTML: required im ersten Radio und Ruf an form.reportValidity() (oder überlassen Sie die Übermittlung dem Browser). Für eine schönere Benutzeroberfläche zeigen Sie eine kurze Inline-Fehler in der Nähe der Gruppe nachdem der erste Versuch, und klar zum Wandel.
role="radiogroup"?Nicht für native Radios. Eine richtige fieldset + legend gibt Bildschirmlesern bereits den richtigen Kontext. Fügen Sie ARIA nur hinzu, wenn Sie ein vollständig benutzerdefiniert Widget (wenn möglich vermeiden).
Folgemaßnahmen ein-/ausblenden nachdem eine Auswahl. Wenn ausgeblendet, auch deaktivieren diese Steuerelemente, sodass sie außerhalb der Tabulatorreihenfolge liegen und nicht übermittelt werden. Wenn sie angezeigt werden, verschieben Sie den Fokus sinnvoll und stellen Sie sicher, dass die Beschriftungen klar bleiben.
Tastaturfluss, sichtbarer Fokus, Screenreader-Ansagen (Legende vorlesen, ausgewählter Status gesprochen), mobile Trefferbereiche, Validierungszeitpunkt (kein frühes Nörgeln) und ausgewählte Werte fortdauern bei serverseitigem Fehler.