Zurück zur Startseite

Deutsche Gesetze

Internationale Standards

Zurück zur Startseite
Best Practices

Mobile Barrierefreiheit Best Practices

Ein umfassender Leitfaden zum Erstellen barrierefreier iOS- und Android-Anwendungen - mit nativen Apps, Hybrid-Frameworks, Touch-Targets, Gesten, Screen Readern und plattformspezifischen Barrierefreiheitsfunktionen

Mobile-First Barrierefreiheit
Mit über 60% des Web-Traffics von mobilen Geräten und Milliarden von Menschen, die ausschließlich mobil auf das Internet zugreifen, ist mobile Barrierefreiheit nicht optional. WCAG 2.1 führte 17 neue Kriterien ein, die speziell mobile Anforderungen adressieren. Dieser Leitfaden deckt sowohl native Apps als auch mobile Web-Erlebnisse ab.

Einführung in Mobile Barrierefreiheit

Warum Mobile Barrierefreiheit wichtig ist

Mobile Geräte sind zur primären Art geworden, wie Milliarden von Menschen auf digitale Inhalte und Dienste zugreifen. Für viele Nutzer mit Behinderungen sind mobile Geräte mit integrierten Barrierefreiheitsfunktionen wie Screen Readern, Sprachsteuerung und Vergrößerung erschwinglicher und zugänglicher als traditionelle assistive Technologien, die teure Desktop-Software oder -Hardware erfordern.

Wichtige Überlegungen zur mobilen Barrierefreiheit:

  • Kleine Bildschirme: Begrenzter Platz erfordert sorgfältige Priorisierung und Organisation
  • Touch-Oberflächen: Touch-Targets müssen groß genug und angemessen beabstandet sein
  • Nutzungskontext: Mobile Nutzer sind oft unterwegs, bei unterschiedlichen Lichtverhältnissen oder beim Multitasking
  • Plattform-Vielfalt: iOS und Android haben unterschiedliche Barrierefreiheits-APIs und Screen Reader
  • Bewegung und Gesten: Komplexe Gesten können für Nutzer mit motorischen Behinderungen schwierig sein
  • Wechselnde Fähigkeiten: Umweltfaktoren (helles Sonnenlicht, Lärm) erzeugen temporäre Behinderungen

iOS vs Android Barrierefreiheit

Beide großen mobilen Plattformen bieten robuste Barrierefreiheitsfunktionen, unterscheiden sich aber in der Implementierung:

Funktion iOS Android
Screen Reader VoiceOver (integriert) TalkBack (integriert)
Aktivierung Dreifach-Klick Home/Seitentaste oder Einstellungen Lautstärketasten oder Einstellungen
Gesten Nach rechts/links wischen zum Navigieren, Doppeltippen zum Aktivieren Nach rechts/links wischen zum Navigieren, Doppeltippen zum Aktivieren
Sprachsteuerung Voice Control (getrennt von Siri) Voice Access
Vergrößerung Zoom (3-Finger-Doppeltippen) Vergrößerung (Dreifach-Tippen oder Taste)
Anzeigeoptionen Display-Anpassungen, Größerer Text Schriftgröße, Anzeigegröße, Farbkorrektur
Switch-Steuerung Switch Control Switch Access

Mobile Barrierefreiheitsstandards

Mobile Apps müssen folgenden Standards entsprechen:

  • WCAG 2.1 Level AA: Funktionale Anforderungen gelten für mobile (mit plattformgerechten Implementierungen)
  • EN 301 549: Europäischer Standard umfasst mobile App-Anforderungen
  • Section 508: US-Bundesstandard aktualisiert um mobile zu inkludieren
  • Plattform-Richtlinien: iOS Human Interface Guidelines und Android Material Design enthalten Barrierefreiheitsanforderungen

iOS Native App Barrierefreiheit

UIKit Barrierefreiheit

Elemente barrierefrei machen

Alle UI-Elemente sollten für VoiceOver zugänglich sein. UIKit-Steuerelemente sind standardmäßig barrierefrei, aber benutzerdefinierte Views benötigen explizite Konfiguration.

// Swift - Making a custom view accessible
class CustomButton: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupAccessibility()
    }

    func setupAccessibility() {
        // Make the view accessible
        isAccessibilityElement = true

        // Set accessibility label (what the element is)
        accessibilityLabel = "Submit form"

        // Set accessibility trait (what kind of element)
        accessibilityTraits = .button

        // Optional: Set accessibility hint (what it does)
        accessibilityHint = "Double tap to submit the form"

        // Optional: Set accessibility value (current state)
        // accessibilityValue = "Not submitted"
    }
}

Accessibility Labels und Hints

Best Practices für Labels und Hints:

  • Label: Kurze, beschreibende Substantivphrase (z.B. "Zum Warenkorb hinzufügen", nicht "Button, der Artikel zum Warenkorb hinzufügt")
  • Hint: Beschreibt das Ergebnis einer Aktion, nur wenn nicht offensichtlich aus dem Label
  • Value: Aktueller Zustand oder Wert (z.B. "Ausgewählt", "3 von 5 Sternen")
  • Elementtyp nicht im Label nennen (VoiceOver kündigt dies über Traits an)
  • Labels kurz halten - Nutzer navigieren durch Wischen durch viele Elemente
// Good examples
button.accessibilityLabel = "Play"
button.accessibilityHint = "Starts playback"

slider.accessibilityLabel = "Volume"
slider.accessibilityValue = "\(Int(slider.value * 100))%"

// Bad examples
button.accessibilityLabel = "Play button" // "button" is redundant
button.accessibilityHint = "Button" // Not helpful
textField.accessibilityLabel = "Type here" // Should describe what to type

Accessibility Traits

Traits sagen VoiceOver, welche Art von Element es ist und wie man damit interagiert.

// Common accessibility traits
.button          // "Button" - double tap to activate
.link            // "Link" - opens content
.searchField     // "Search field" - brings up keyboard
.image           // "Image" - non-interactive image
.staticText      // Plain text
.header          // Heading (navigable with rotor)
.selected        // "Selected" - current state
.notEnabled      // "Dimmed" - disabled state
.adjustable      // Can be incremented/decremented with swipe up/down

// Combining traits
view.accessibilityTraits = [.button, .selected]

// Custom controls
view.accessibilityTraits = .adjustable
view.accessibilityValue = "Medium"

// Implementing adjustable
override func accessibilityIncrement() {
    // User swiped up
    increaseValue()
}

override func accessibilityDecrement() {
    // User swiped down
    decreaseValue()
}

Elemente gruppieren

Gruppieren Sie zusammenhängende Elemente, damit VoiceOver sie als ein einzelnes Element behandelt und so die Navigationskomplexität reduziert.

// Group a card with image, title, and description
cardView.isAccessibilityElement = true
cardView.accessibilityLabel = "\(title), \(description)"
cardView.accessibilityTraits = .button

// Hide child elements from VoiceOver
imageView.isAccessibilityElement = false
titleLabel.isAccessibilityElement = false
descriptionLabel.isAccessibilityElement = false

SwiftUI Barrierefreiheit

SwiftUI bietet deklarative Modifikatoren für Barrierefreiheit:

// SwiftUI accessibility modifiers
Button(action: submit) {
    Text("Submit")
}
.accessibilityLabel("Submit form")
.accessibilityHint("Double tap to submit")
.accessibilityAddTraits(.isButton)

// Grouping
HStack {
    Image("star")
    Text("4.5 stars")
    Text("(120 reviews)")
}
.accessibilityElement(children: .combine)
.accessibilityLabel("Rating: 4.5 stars, 120 reviews")

// Custom actions
Text("Article title")
    .accessibilityActions {
        Button("Share") { shareArticle() }
        Button("Bookmark") { bookmarkArticle() }
    }

// Value and adjustable
Slider(value: $volume, in: 0...100)
    .accessibilityLabel("Volume")
    .accessibilityValue("\(Int(volume))%")

// Hidden elements
Image(decorative: "background")
    .accessibilityHidden(true)

Testen mit VoiceOver

So testen Sie mit VoiceOver:

  1. VoiceOver aktivieren: Einstellungen → Bedienungshilfen → VoiceOver (oder Dreifach-Klick Home/Seitentaste)
  2. Grundlegende Gesten:
    • Nach rechts wischen: Nächstes Element
    • Nach links wischen: Vorheriges Element
    • Doppeltippen: Element aktivieren
    • Drei-Finger-Wischen: Scrollen
    • Zwei-Finger-Doppeltippen: Magic Tap (primäre Aktion)
    • Rotor: Zwei-Finger-Drehung für Navigationsverknüpfungen
  3. Was zu überprüfen ist:
    • Können Sie zu allen interaktiven Elementen navigieren?
    • Sind Labels klar und prägnant?
    • Kündigen Elemente ihren Typ korrekt an?
    • Ist die Navigationsreihenfolge logisch?
    • Sind dekorative Elemente richtig ausgeblendet?
    • Funktionieren benutzerdefinierte Steuerelemente mit Nach-oben/unten-Wischen?
Accessibility Inspector
Verwenden Sie Xcodes Accessibility Inspector, um Ihre App zu prüfen:
  • Xcode → Open Developer Tool → Accessibility Inspector
  • Automatisierte Audits ausführen
  • Element-Hierarchie inspizieren
  • Mit simuliertem VoiceOver testen

Android Native App Barrierefreiheit

Android Barrierefreiheit Grundlagen

Content Descriptions

Content Descriptions sind das Android-Äquivalent zu Accessibility Labels.

<!-- XML -->
<ImageButton
    android:id="@+id/playButton"
    android:src="@drawable/ic_play"
    android:contentDescription="@string/play_button" />

<!-- Decorative images -->
<ImageView
    android:src="@drawable/decorative"
    android:importantForAccessibility="no" />

// Kotlin - Setting programmatically
button.contentDescription = "Play audio"

// Dynamic content description
button.contentDescription = if (isPlaying) {
    "Pause audio"
} else {
    "Play audio"
}

Formularfelder beschriften

<!-- Using android:hint -->
<EditText
    android:id="@+id/emailInput"
    android:hint="Email address"
    android:inputType="textEmailAddress" />

<!-- Using android:labelFor for separate labels -->
<TextView
    android:id="@+id/passwordLabel"
    android:text="Password"
    android:labelFor="@id/passwordInput" />

<EditText
    android:id="@+id/passwordInput"
    android:inputType="textPassword" />

Benutzerdefinierte Accessibility Actions

// Kotlin - Adding custom actions
ViewCompat.addAccessibilityAction(
    view,
    "Share"
) { view, arguments ->
    shareContent()
    true
}

ViewCompat.addAccessibilityAction(
    view,
    "Bookmark"
) { view, arguments ->
    bookmarkContent()
    true
}

// User can access these via TalkBack's Actions menu

Gruppierung und Fokusreihenfolge

<!-- Group related content -->
<LinearLayout
    android:screenReaderFocusable="true"
    android:contentDescription="Product: Phone, $599, 4.5 stars">

    <ImageView
        android:src="@drawable/phone"
        android:importantForAccessibility="no" />

    <TextView
        android:text="Phone"
        android:importantForAccessibility="no" />

    <TextView
        android:text="$599"
        android:importantForAccessibility="no" />
</LinearLayout>

<!-- Control focus order -->
<View
    android:id="@+id/firstElement"
    android:nextFocusForward="@+id/secondElement" />

Jetpack Compose Barrierefreiheit

// Compose accessibility modifiers
Button(
    onClick = { submit() },
    modifier = Modifier.semantics {
        contentDescription = "Submit form"
        role = Role.Button
    }
) {
    Text("Submit")
}

// Merge descendant semantics
Row(
    modifier = Modifier.semantics(mergeDescendants = true) {
        contentDescription = "4.5 stars, 120 reviews"
    }
) {
    Icon(Icons.Filled.Star, contentDescription = null)
    Text("4.5")
    Text("(120 reviews)")
}

// Custom actions
Text(
    "Article title",
    modifier = Modifier.semantics {
        customActions = listOf(
            CustomAccessibilityAction("Share") {
                shareArticle()
                true
            },
            CustomAccessibilityAction("Bookmark") {
                bookmarkArticle()
                true
            }
        )
    }
)

// State descriptions
Checkbox(
    checked = isChecked,
    onCheckedChange = { isChecked = it },
    modifier = Modifier.semantics {
        stateDescription = if (isChecked) "Checked" else "Unchecked"
    }
)

Testen mit TalkBack

So testen Sie mit TalkBack:

  1. TalkBack aktivieren: Einstellungen → Bedienungshilfen → TalkBack (oder Lautstärketasten-Verknüpfung)
  2. Grundlegende Gesten:
    • Nach rechts wischen: Nächstes Element
    • Nach links wischen: Vorheriges Element
    • Doppeltippen: Element aktivieren
    • Zwei-Finger-Wischen: Scrollen
    • Lesesteuerungsmenü: Nach unten dann nach rechts wischen
  3. Test-Checkliste:
    • Alle Elemente haben Content Descriptions
    • Formularfelder haben Labels
    • Fokusreihenfolge ist logisch
    • Benutzerdefinierte Actions funktionieren korrekt
    • Zustandsänderungen werden angekündigt
    • Dekorative Elemente sind ausgeblendet
Accessibility Scanner
Verwenden Sie Googles Accessibility Scanner App, um Barrierefreiheitsprobleme zu identifizieren:
  • Installation aus dem Google Play Store
  • Berechtigungen erteilen
  • Jeden Bildschirm in Ihrer App scannen
  • Verbesserungsvorschläge überprüfen

Touch-Targets und Gesten

Touch-Target-Größe

WCAG 2.1 Erfolgskriterium 2.5.5 (Level AAA) erfordert Touch-Targets von mindestens 44×44 CSS-Pixeln. Sowohl iOS als auch Android empfehlen mindestens 44×44 Punkte (iOS) / 48×48 dp (Android).

/* iOS - Minimum touch target */
button.frame(minWidth: 44, minHeight: 44)

// Android - Minimum touch target
<Button
    android:minWidth="48dp"
    android:minHeight="48dp" />

// If visual size must be smaller, increase touch area
view.frame(width: 24, height: 24)
    .contentShape(Rectangle())
    .padding(10) // Creates 44×44 touch area

Touch-Target Best Practices:

  • Mindestens 8 Pixel (8pt/8dp) Abstand zwischen benachbarten Touch-Targets
  • Den gesamten Button/Link-Bereich anklickbar machen, nicht nur Text oder Icon
  • In kompakten Layouts (Toolbars) Mindestgröße beibehalten, auch wenn Abstands-Anpassungen erforderlich sind
  • Nutzer mit motorischen Beeinträchtigungen, Arthritis oder Parkinson berücksichtigen

Gesten-Barrierefreiheit

Alternativen zu komplexen Gesten bereitstellen

WCAG 2.1 erfordert Alternativen zu pfadbasierten und mehrpunktigen Gesten (2.5.1).

  • Pfadbasiert: Gesten, die einen bestimmten Pfad erfordern (Wischformen, Zeichnen) benötigen einfachere Alternativen
  • Mehrpunktig: Pinch-to-Zoom, Mehrfinger-Wischen benötigen Ein-Finger-Alternativen
  • Mehrfach-Tippen: Doppeltippen, Dreifach-Tippen sollten Ein-Tipp-Alternativen haben
// GOOD: Pinch to zoom with buttons
ZoomableImage()
    .zoomButtons() // Provides +/- buttons as alternative

// GOOD: Swipe to delete with button
List {
    ForEach(items) { item in
        ItemRow(item)
            .swipeActions {
                Button(role: .destructive) {
                    delete(item)
                } label: {
                    Label("Delete", systemImage: "trash")
                }
            }
    }
}

// BAD: Required complex gesture with no alternative
// Drawing signature with no "Type name" option

Bewegungssteuerung

Bieten Sie Alternativen zu bewegungsbasierten Steuerungen (Schütteln, Neigen) gemäß WCAG 2.5.4.

// GOOD: Shake to undo with button alternative
.onShake {
    undo()
}
// Also provide:
Button("Undo", action: undo)

// GOOD: Respect motion preferences
if !accessibilityPrefersReducedMotion {
    // Use motion-based feature
} else {
    // Use static alternative
}

Responsives Mobile Design

Textgröße und Umbruch

Unterstützen Sie Benutzer-Textgrößen-Einstellungen (WCAG 1.4.4 - Text vergrößern, 1.4.10 - Umbruch).

// iOS - Dynamic Type
Text("Hello")
    .font(.body) // Automatically scales with user settings

// Custom fonts with scaling
    .font(.custom("MyFont", size: 17, relativeTo: .body))

// Android - Scalable text
<TextView
    android:text="Hello"
    android:textSize="16sp" /> <!-- Use sp, not dp -->

// Compose
Text(
    "Hello",
    fontSize = 16.sp // Scales with user settings
)

Text-Skalierungs Best Practices:

  • Verwenden Sie Plattform-Dynamic-Text (Dynamic Type auf iOS, sp-Einheiten auf Android)
  • Testen mit größter Textgröße (Einstellungen → Anzeige → Textgröße)
  • Stellen Sie sicher, dass Layouts elegant umbrechen, nicht abschneiden
  • Erwägen Sie horizontales Scrollen für sehr großen Text bei Bedarf
  • Verwenden Sie keine festen Höhen, die zu Text-Clipping führen

Orientierungsunterstützung

Unterstützen Sie sowohl Hoch- als auch Querformat, es sei denn, eine bestimmte Orientierung ist wesentlich (WCAG 1.3.4).

  • Orientierung nicht sperren, es sei denn absolut notwendig (z.B. spezifische AR-Erlebnisse)
  • Stellen Sie sicher, dass alle Inhalte und Funktionen in beiden Orientierungen funktionieren
  • Layout intelligent an verfügbaren Platz anpassen
  • Nutzer mit montierten Geräten benötigen möglicherweise eine bestimmte Orientierung

Farbkontrast auf Mobilgeräten

Mobile Geräte werden oft im Freien bei hellem Sonnenlicht verwendet, was Kontrast noch kritischer macht.

  • Folgen Sie WCAG 2.1 Kontrastanforderungen: 4.5:1 für normalen Text, 3:1 für großen Text
  • Testen bei hellem Sonnenlicht
  • Unterstützen Sie Dark Mode mit angemessenen Kontrastverhältnissen
  • Verlassen Sie sich nicht nur auf Farbe, um Informationen zu vermitteln
// iOS - Dark mode support
Color("PrimaryText") // Defined in asset catalog with light/dark variants

Text("Important")
    .foregroundColor(.primary) // Automatically adapts

// Android - Dark mode
<resources>
    <color name="primaryText">#000000</color>
</resources>

<!-- res/values-night/colors.xml -->
<resources>
    <color name="primaryText">#FFFFFF</color>
</resources>

Hybrid- und Cross-Platform-Apps

React Native Barrierefreiheit

import { View, Text, TouchableOpacity } from 'react-native';

<TouchableOpacity
  accessible={true}
  accessibilityLabel="Submit form"
  accessibilityHint="Double tap to submit"
  accessibilityRole="button"
  onPress={handleSubmit}>
  <Text>Submit</Text>
</TouchableOpacity>

// Hide decorative elements
<Image
  source={require('./decoration.png')}
  accessibilityElementsHidden={true} // iOS
  importantForAccessibility="no" // Android
/>

// Group elements
<View
  accessible={true}
  accessibilityLabel="Product: Phone, $599, 4.5 stars">
  <Image source={productImage} />
  <Text>Phone</Text>
  <Text>$599</Text>
  <Text>4.5 ★</Text>
</View>

Flutter Barrierefreiheit

// Flutter accessibility
Semantics(
  label: 'Submit form',
  hint: 'Double tap to submit',
  button: true,
  child: ElevatedButton(
    onPressed: submit,
    child: Text('Submit'),
  ),
)

// Merge semantics
Semantics(
  label: '4.5 stars, 120 reviews',
  child: Row(
    children: [
      Icon(Icons.star),
      Text('4.5'),
      Text('(120 reviews)'),
    ],
  ),
)

// Exclude from semantics
ExcludeSemantics(
  child: Image.asset('decoration.png'),
)
Auf echten Geräten testen
Testen Sie immer auf physischen Geräten mit echten Screen Readern (VoiceOver/TalkBack). Simulatoren und Emulatoren replizieren nicht vollständig die Screen Reader-Erfahrung. Testen Sie mit verschiedenen Textgrößen, Farbschemata und aktivierten Barrierefreiheitseinstellungen.