Communitygithub.com

Blaise1030/astro-marketing

Überprüfe und verbessere die Barrierefreiheit im Web gemäß WCAG 2.2. Verwende diese Anleitung, wenn nach „Barrierefreiheit verbessern“, „a11y-Prüfung“, „WCAG-Konformität“, „Screenreader-Unterstützung“, „Tastaturnavigation“ oder „zugänglich machen“ gefragt wird.

Was ist astro-marketing?

Dieser Skill bietet eine umfassende, evidenzbasierte Arbeitsanleitung zur Verbesserung der Zugänglichkeit von Webseiten nach WCAG 2.2. Er beschreibt einen detaillierten Prüfworkflow, der mit einem Live-Lighthouse-Audit beginnt, die Ergebnisse nutzt, um betroffene Komponenten gezielt zu identifizieren, und mit einer manuellen Überprüfung des Accessibility-Trees und der Tastaturbedienung endet. Der Leitfaden deckt alle vier WCAG-Prinzipien (wahrnehmbar, bedienbar, verständlich, robust) ab und enthält spezifische Codebeispiele für häufige Probleme wie fehlende Alternativtexte, unzureichende Farbkontraste und Tastaturfallen. Er unterstützt Entwickler auf allen Plattformen, indem er automatische Prüfungen (Lighthouse, axe) mit manuellen Tests kombiniert und so eine ganzheitliche Sicherstellung der Barrierefreiheit ermöglicht.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Blaise1030/astro-marketing/tree/HEAD/.agents/skills/accessibility

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Vorschau

Aus dem Skill-README

astro-marketing preview
astro-marketing preview
astro-marketing preview

Dokumentation

Barrierefreiheit (a11y)

Umfassende Richtlinien zur Barrierefreiheit basierend auf WCAG 2.2 und Lighthouse-Accessibility-Audits. Ziel: Inhalte für alle nutzbar machen, einschließlich Menschen mit Behinderungen.

Evidenzbasierter Prüfworkflow

Wenn eine gerenderte Seite verfügbar ist:

  1. Führe einen Live-Lighthouse-Accessibility-Audit durch, wenn diese Funktion verfügbar ist; mit Chrome DevTools MCP verwende lighthouse_audit. Verwende den mobilen Navigationsmodus für eine öffentliche Seite oder den Snapshot-Modus, wenn ein Neuladen den authentifizierten oder vom Benutzer erstellten Zustand verlieren würde.
  2. Verwende fehlgeschlagene Audit-Knoten, um die relevante Komponente oder Vorlage zu lokalisieren, anstatt das gesamte Repository nach generischen Mustern zu durchsuchen.
  3. Untersuche einen gerenderten Snapshot des Accessibility-Trees auf Namen, Rollen, Zustände, Orientierungspunkte und Überschriftenstruktur; mit Chrome DevTools MCP verwende take_snapshot. Teste den betroffenen Ablauf mit der Tastatur.
  4. Korrigiere die Quelle und führe dann dasselbe Audit und die manuelle Interaktion erneut durch.

Falls die Live-Tools nicht verfügbar sind, verwende Lighthouse CLI oder axe für die automatisierte Abdeckung und führe dieselben manuellen Prüfungen durch. Automatisierte Tools erkennen nur einen Teil der Barrieren: Eine Punktzahl von 100 ist keine WCAG-Konformität, und eine niedrige Punktzahl ersetzt keine nachweislichen Probleme auf Einzelfallebene.

WCAG-Prinzipien: POUR

PrinzipBeschreibung
WahrnehmbarInhalte können durch verschiedene Sinne wahrgenommen werden
BedienbarDie Benutzeroberfläche kann von allen Benutzern bedient werden
VerständlichInhalte und Benutzeroberfläche sind verständlich
RobustInhalte funktionieren mit assistiven Technologien

Konformitätsstufen

StufeAnforderungZiel
AMindestanforderung an BarrierefreiheitMuss bestanden werden
AAStandardkonformitätSollte bestanden werden (rechtliche Anforderung in vielen Ländern)
AAAErweiterte BarrierefreiheitWünschenswert

Wahrnehmbar

Textalternativen (1.1)

Bilder benötigen Alt-Text:

<!-- ❌ Fehlender Alt-Text -->
<img src="chart.png">

<!-- ✅ Beschreibender Alt-Text -->
<img src="chart.png" alt="Balkendiagramm, das einen Anstieg der Q3-Umsätze um 40 % zeigt">

<!-- ✅ Dekoratives Bild (leerer Alt-Text) -->
<img src="decorative-border.png" alt="" role="presentation">

<!-- ✅ Komplexes Bild mit längerer Beschreibung -->
<figure>
  <img src="infographic.png" alt="Infografik zu Markttrends 2024" 
       aria-describedby="infographic-desc">
  <figcaption id="infographic-desc">
    <!-- Detaillierte Beschreibung -->
  </figcaption>
</figure>

Symbol-Buttons benötigen zugängliche Namen:

<!-- ❌ Kein zugänglicher Name -->
<button><svg><!-- Menü-Symbol --></svg></button>

<!-- ✅ Mit aria-label -->
<button aria-label="Menü öffnen">
  <svg aria-hidden="true"><!-- Menü-Symbol --></svg>
</button>

<!-- ✅ Mit visuell verstecktem Text -->
<button>
  <svg aria-hidden="true"><!-- Menü-Symbol --></svg>
  <span class="visually-hidden">Menü öffnen</span>
</button>

Visuell versteckte Klasse:

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

Farbkontrast (1.4.3, 1.4.6)

TextgrößeAA-MindestwertAAA-verbessert
Normaler Text (< 18px / < 14px fett)4,5:17:1
Großer Text (≥ 18px / ≥ 14px fett)3:14,5:1
UI-Komponenten & Grafiken3:13:1
/* ❌ Niedriger Kontrast (2,5:1) */
.low-contrast {
  color: #999;
  background: #fff;
}

/* ✅ Ausreichender Kontrast (7:1) */
.high-contrast {
  color: #333;
  background: #fff;
}

/* ✅ Fokus-Zustände benötigen ebenfalls Kontrast (3:1 zum Hintergrund, WCAG 1.4.11) */
:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

Nicht allein auf Farbe verlassen:

<!-- ❌ Nur Farbe zeigt Fehler an -->
<input class="error-border">
<style>.error-border { border-color: red; }</style>

<!-- ✅ Farbe + Symbol + Text -->
<div class="field-error">
  <input aria-invalid="true" aria-describedby="email-error">
  <span id="email-error" class="error-message">
    <svg aria-hidden="true"><!-- Fehler-Symbol --></svg>
    Bitte geben Sie eine gültige E-Mail-Adresse ein
  </span>
</div>

Medienalternativen (1.2)

<!-- Video mit Untertiteln -->
<video controls>
  <source src="video.mp4" type="video/mp4">
  <track kind="captions" src="captions.vtt" srclang="en" label="Englisch" default>
  <track kind="descriptions" src="descriptions.vtt" srclang="en" label="Beschreibungen">
</video>

<!-- Audio mit Transkript -->
<audio controls>
  <source src="podcast.mp3" type="audio/mp3">
</audio>
<details>
  <summary>Transkript</summary>
  <p>Vollständiger Transkripttext...</p>
</details>

Bedienbar

Tastaturzugänglichkeit (2.1)

Die gesamte Funktionalität muss per Tastatur zugänglich sein. Bevorzuge native interaktive Elemente – <button>, <a href> und Formularsteuerelemente übernehmen die Aktivierung per Eingabetaste/Leertaste, den Fokus und die assistive Technologie-Semantik automatisch. Füge nur dann manuelle Tastaturbehandlung hinzu, wenn du kein natives Element verwenden kannst.

<!-- ❌ Nicht-interaktives Element nur mit Klick: nicht fokussierbar, keine Tastaturaktivierung -->
<div class="card" onclick="handleAction()">Öffnen</div>

<!-- ✅ Am besten: natives Button-Element verwenden -->
<button type="button" onclick="handleAction()">Öffnen</button>
// ✅ Wenn du ein nicht-interaktives Element verwenden MUSST (z. B. div mit role="button"),
// mache es fokussierbar UND behandle die Tastaturaktivierung. Füge dies NICHT zu einem nativen
// <button> hinzu – Enter/Leertaste lösen bereits einen Klick aus, sodass du doppelt auslösen würdest.
element.setAttribute('role', 'button');
element.setAttribute('tabindex', '0');
element.addEventListener('click', handleAction);
element.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' || e.key === ' ') {
    e.preventDefault();
    handleAction();
  }
});

Keine Tastaturfallen. Benutzer müssen mit der Tabulatortaste in jede Komponente hinein- und wieder hinaus navigieren können. Verwende das Modal-Focus-Trap-Muster für Dialoge – das native <dialog>-Element erledigt dies automatisch.

Sichtbarer Fokus (2.4.7)

/* ❌ Niemals Fokus-Ringe entfernen */
*:focus { outline: none; }

/* ✅ :focus-visible für tastaturnur-Fokus verwenden */
:focus {
  outline: none;
}

:focus-visible {
  outline: 2px solid currentColor; /* erbt Textfarbe → bereits auf Kontrast geprüft */
  outline-offset: 2px;
}

/* ✅ Oder eine Markenfarbe wählen und ≥3:1-Kontrast zu jedem Hintergrund prüfen */
button:focus-visible {
  box-shadow: 0 0 0 3px rgba(0, 95, 204, 0.5);
}

Fokus nicht verdeckt (2.4.11) – neu in 2.2

Wenn ein Element den Tastaturfokus erhält, darf es nicht vollständig durch andere vom Autor erstellte Inhalte wie sticky-Header, Footer oder überlappende Panels verdeckt werden. Auf Stufe AAA (2.4.12) darf kein Teil des fokussierten Elements verborgen sein.

/* ✅ Sticky-Header beim Scrollen zu fokussierten Elementen berücksichtigen */
:target {
  scroll-margin-top: 80px;
}

/* ✅ Sicherstellen, dass fokussierte Elemente fixierte/statische Balken freigeben */
:focus {
  scroll-margin-top: 80px;
  scroll-margin-bottom: 60px;
}

Sprunglinks (2.4.1)

Biete einen Sprunglink an, damit Tastaturnutzer repetitive Navigation umgehen können. Siehe das Sprunglink-Muster für vollständiges Markup und Styles.

Zielgröße (2.5.8) – neu in 2.2

Interaktive Ziele müssen mindestens 24 × 24 CSS-Pixel (AA) groß sein. Ausnahmen: Inline-Textlinks, Elemente, deren Größe vom Browser gesteuert wird, und Ziele, bei denen ein 24 Pixel großer Kreis, der um die Begrenzungsbox zentriert ist, kein anderes Ziel überlappt.

/* ✅ Mindestzielgröße */
button,
[role="button"],
input[type="checkbox"] + label,
input[type="radio"] + label {
  min-width: 24px;
  min-height: 24px;
}

/* ✅ Komfortable Zielgröße (empfohlen 44×44) */
.touch-target {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

Ziehbewegungen (2.5.7) – neu in 2.2

Jede Aktion, die ein Ziehen erfordert, muss eine Einzelzeigeralternative haben (z. B. Schaltflächen, Eingabefelder). Siehe das Ziehbewegungen-Muster für ein Beispiel einer sortierbaren Liste.

Zeitlimits (2.2)

// Benutzern erlauben, Zeitlimits zu verlängern
function showSessionWarning() {
  const modal = createModal({
    title: 'Sitzung läuft ab',
    content: 'Ihre Sitzung läuft in 2 Minuten ab.',
    actions: [
      { label: 'Sitzung verlängern', action: extendSession },
      { label: 'Abmelden', action: logout }
    ],
    timeout: 120000
  });
}

Bewegung (2.3)

/* Präferenz für reduzierte Bewegung respektieren */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

Verständlich

Seitensprache (3.1.1)

<!-- ❌ Keine Sprache angegeben -->
<html>

<!-- ✅ Sprache angegeben -->
<html lang="de">

<!-- ✅ Sprachwechsel innerhalb der Seite -->
<p>Das französische Wort für Hallo ist <span lang="fr">bonjour</span>.</p>

Konsistente Navigation (3.2.3)

<!-- Navigation sollte über Seiten hinweg konsistent sein -->
<nav aria-label="Hauptnavigation">
  <ul>
    <li><a href="/" aria-current="page">Startseite</a></li>
    <li><a href="/products">Produkte</a></li>
    <li><a href="/about">Über uns</a></li>
  </ul>
</nav>

Konsistente Hilfe (3.2.6) – neu in 2.2

Wenn ein Hilfemechanismus (Kontaktinformationen, Chat-Widget, FAQ-Link, Selbsthilfeoption) auf mehreren Seiten wiederholt wird, muss er jedes Mal in der gleichen relativen Reihenfolge erscheinen. Benutzer, die auf eine konsistente Platzierung angewiesen sind, sollten nicht auf jeder Seite nach Hilfe suchen müssen.

Formular-Beschriftungen (3.3.2)

Jedes Eingabefeld benötigt eine programmatisch zugeordnete Beschriftung. Siehe das Formular-Beschriftungen-Muster für explizite, implizite und anleitende Beispiele.

Fehlerbehandlung (3.3.1, 3.3.3)

Fehler mit role="alert" oder aria-live an Screenreader ankündigen, bei ungültigen Feldern aria-invalid="true" setzen und beim Absenden auf den ersten Fehler fokussieren. Siehe das Fehlerbehandlungs-Muster für vollständiges Markup und JS.

Redundante Eingabe (3.3.7) – neu in 2.2

Zwinge Benutzer nicht, Informationen, die sie bereits in derselben Sitzung angegeben haben, erneut einzugeben. Fülle aus früheren Schritten automatisch aus oder lasse Benutzer aus zuvor eingegebenen Werten auswählen. Ausnahmen: Sicherheitsbestätigungen und abgelaufene Inhalte.

<!-- ✅ Lieferadresse automatisch aus Rechnungsadresse übernehmen -->
<fieldset>
  <legend>Lieferadresse</legend>
  <label>
    <input type="checkbox" id="same-as-billing" checked>
    Identisch mit Rechnungsadresse
  </label>
  <!-- Felder werden automatisch ausgefüllt, wenn aktiviert -->
</fieldset>

Zugängliche Authentifizierung (3.3.8) – neu in 2.2

Anmeldevorgänge dürfen nicht auf kognitive Funktionstests angewiesen sein (z. B. ein Passwort merken, ein Rätsel lösen), es sei denn, mindestens eines der folgenden Kriterien ist erfüllt:

  • Ein Kopieren-Einfügen- oder Autofill-Mechanismus ist verfügbar
  • Es gibt eine alternative Methode (z. B. Passkey, SSO, E-Mail-Link)
  • Der Test verwendet Objekterkennung oder persönliche Inhalte (nur AA; AAA entfernt diese Ausnahme)
<!-- ✅ Einfügen in Passwortfelder erlauben -->
<input type="password" id="password" autocomplete="current-password">

<!-- ✅ Passwortlose Alternativen anbieten -->
<button type="button">Mit Passkey anmelden</button>
<button type="button">Anmeldelink per E-Mail senden</button>

Robust

ARIA-Verwendung (4.1.2)

Nativ-Elemente bevorzugen:

<!-- ❌ ARIA-Rolle auf div -->
<div role="button" tabindex="0">Klick mich</div>

<!-- ✅ Natives Button-Element -->
<button>Klick mich</button>

<!-- ❌ ARIA-Checkbox -->
<div role="checkbox" aria-checked="false">Option</div>

<!-- ✅ Native Checkbox -->
<label><input type="checkbox"> Option</label>

Wenn ARIA benötigt wird, verwende die korrekten Rollen und Zustände. Siehe das ARIA-Tabs-Muster für ein vollständiges Tablist-Beispiel.

Live-Regionen (4.1.3)

Verwende aria-live-Regionen, um dynamische Inhaltsänderungen anzukündigen, ohne den Fokus zu verschieben. Siehe das Live-Regionen-Muster für das Markup und einen showNotification()-Helfer.


Test-Checkliste

Automatisierte Tests

Bevorzuge ein Live-Lighthouse-Audit, das direkt die fehlgeschlagenen gerenderten Knoten an den Agenten zurückgibt. Mit Chrome DevTools MCP ist dies lighthouse_audit. Andernfalls:

# Lighthouse-Barrierefreiheitsaudit
npx lighthouse https://example.com --only-categories=accessibility

# axe-core
npm install @axe-core/cli -g
axe https://example.com

Manuelle Tests

  • Tastaturnavigation: Gesamte Seite mit Tab durchgehen, Eingabetaste/Leertaste zum Aktivieren verwenden
  • Screenreader: Test mit VoiceOver (Mac), NVDA (Windows) oder TalkBack (Android)
  • Zoom: Inhalt bei 200 % Zoom nutzbar
  • Hoher Kontrast: Test mit Windows High Contrast Mode
  • Reduzierte Bewegung: Test mit prefers-reduced-motion: reduce
  • Fokus-Reihenfolge: Logisch und folgt der visuellen Reihenfolge
  • Zielgröße: Interaktive Elemente erfüllen das Minimum von 24×24px

Siehe die Screenreader-Befehlsreferenz für VoiceOver- und NVDA-Tastenkombinationen.


Häufige Probleme nach Auswirkung

Kritisch (sofort beheben)

  1. Fehlende Formular-Beschriftungen
  2. Fehlender Bild-Alt-Text
  3. Unzureichender Farbkontrast
  4. Tastaturfallen
  5. Keine Fokus-Indikatoren

Schwerwiegend (vor Veröffentlichung beheben)

  1. Fehlende Seiten-Sprache
  2. Fehlende Überschriftenstruktur
  3. Nicht beschreibender Link-Text
  4. Automatisch abspielende Medien
  5. Fehlende Sprunglinks

Mittelschwer (bald beheben)

  1. Fehlende ARIA-Beschriftungen für Symbole
  2. Inkonsistente Navigation
  3. Fehlende Fehleridentifizierung
  4. Zeitlimits ohne Steuerung
  5. Fehlende Orientierungspunktregionen

Referenzen

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

Verwandte Skills