Barrierefreie Dokumente erstellen mit R und Quarto

Love Data Week 2026

Dr. Björn Fisseler

Vorstellung

Dr. Björn Fisseler

  • Aktuell
    • FernUniversität in Hagen
    • Spezialist für Bildungstechnologie
  • Forschungs- und Arbeitsthemen
    • Barrierefreiheit und Universal Design
    • Lernende mit gesundheitlichen Beeinträchtigungen
    • Inklusive digitale Bildung
    • Bildungstechnologie und KI
  • Fragen? Gerne per Mail an bjoern.fisseler@fernuni-hagen.de

Porträt Björn Fisseler, ein mittelalter Mann mit grauen Haaren lächtelt in die Kamera, trägt ein Sakko und ein weißes Hemd

Überblick

  • Was ist überhaupt digitale Barrierefreiheit und warum ist das wichtig?
  • Grundlagen schaffen
  • Visuelles barrierefrei gestalten
  • Tabellarisches barrierefrei gestalten
  • Barrierefreiheit überprüfen
  • Zusammenfassung

Warum R und Quarto?

  • Quarto
    • Open-Source, kostenfrei verfügbar
    • basiert auf Markdown, ist also plain-text
    • Publikationssystem für wissenschaftliche und technische Dokumente, aber auch Präsentationen, Dahsboards, Webseiten, Blogs, Bücher, ….
    • neben R unterstützt Quarto auch Python, Julia und Observable
  • R
    • weit verbreitete Statistik-Programmiersprache
    • ebenfalls Open-Source und kostenfrei
    • zahlreiche Packages erweitern R und helfen auch bei Inhalten weiter
  • Workflow: Quarto-MD > knitr > MD > Pandoc > Ausgabedokument

Was ist Barrierefreiheit?

Barrierefrei sind […] Systeme der Informationverarbeitung, akustische und visuelle Informationsquellen […], wenn sie für Menschen mit Behinderungen in der allgemein üblichen Weise, ohne besondere Erschwernis und grundsätzlich ohne fremde Hilfe auffindbar, zugänglich und nutzbar sind. Hierbei ist die Nutzung behinderungsbedingt notwendiger Hilfsmittel zulässig. - §4 BGG (Hervorhebungen durch den Verfasser)

Für wen ist Barrierefreiheit wichtig?

Beeinträchtigungen können dauerhaft, vorübergehen oder situativ sein; Illustration von Microsoft Inclusive Design

Vielfalt von Anfang an berücksichtigen

Grundlagen digitaler Barrierefreiheit

Barrierefreie Inhalte folgen dem POUR-Prinzip, d.h. sie sind …

  • Perceivable - wahrnehmbar durch Textalternative, Untertitelung, sie sind unterscheidbar und anpassbar
  • Operable - bedienbar auch per Tastatur, einfach navigierbar, nutzbar ohne Zeitdruck und Anfälle auszulösen
  • Understandable - verständlich, gut lesbar, vorhersehbar und nachvollziehbar gestaltet, und Fehler werden vermieden
  • Robust - robust und kompatibel mit aktuellen und künftigen Werkzeugen

Grundlagen barrierefreier Dokumente

  • Vorteil Markdown: WYSIWYM - What You See Is What You Mean
  • Perceivable / Wahrnehmbar
    • Textalternativen für nicht-textuelle Inhalte
    • Strukturierung mit Elementen für Überschriften, Listen, Zitate
    • Gliederung von Dokumenten
    • Korrekt aufgebaute Tabellen
    • Farbkontraste
  • Operable / Bedienbar
    • Inhaltsverzeichnis bei langen Dokumenten
    • Dokumententitel
    • Sprechende Links
  • Understandable / Verständlich
    • Aussagekräftige Überschriften und Beschriftungen
    • Dokumentensprache angegeben
  • Robust

Aufbau von Quarto-MD-Dokumenten

  • Metadaten verbessern die Barrierefreiheit und Auffindbarkeit
  • YAML-Vorspann
  • Inhalt
    • Markdown mit Inhalt und Codeblöcken
    title: Beispieldokument
    author:
        name: Petra Musterfrau
        orcid: 0000-1234-5678-9123
    lang: de
    ----

    ## Einführung

    ...

Dokumente semantisch strukturieren

  • WYSIWYM: Dokumente mit Überschriften gliedern
  • Überschriftenhierarchie beachten
  • Überschriften in Markdown
    • # : H1

    • ## : H2

    • ### : H3 usw.

  • Tipp: Entweder eine H1/# oder title im YAML-Header
  • Strukturelemente für
    • unnummerierte Listen: *, + -
    • nummerierte Listen: 1., 2., usw.
    • Einrückungen/Zitate: >, >>

Barrierefreies Schreiben

  • Aussagekräftige (“sprechende”) Link-Texte nutzen:
  • Trennstriche
    • Bindestrich, Trennstrich, Minus: —, – oder doch - ?
    • Aus „05.05. – 07.05.“ wird „05.05. bis 07.05.“
  • Genderschreibweisen
    • “bestimmte Schreibweisen (*:_I/-) sind nicht barrierefrei“ > Jein, Screenreader können angepasst werden
    • Im Zweifel einfach geschlechtsneutral (Studierende) schreiben

Barrierefreie Grafiken und Diagramme

Grundlegende Anforderungen und Strategien:

  • Nicht-textuelle Inhalte brauchen eine Textalternative
  • Komplexe Abbildungen um Erläuterungen im Text oder Datentabelle ergänzen
  • Inhalte sollten nicht nur über Farbe vermittelt werden
  • Auf ausreichende Farbkontraste und Wahrnehmbarkeit ohne Farbe achten

Bildschirmfoto Diagram Center Specific Guidelines - Graphs

Balkenmdiagramm, darunter Guidelines und Description sowie eine Tabelle mit den Rohdaten für das Balkendiagramm

Zwei Balkendiagramme übereinander, eines mit Balken in den Farben Rot, Grün und Blau, das andere in Schwarz-weiß

Liniendiagram, betitelt Accessible Version of Line Chart; die Linien sind in Farben und Linienstil unterschiedlich; gepunktete, gestrichelte und durchgezogene Linie

Alternativtexte erstellen

Um was für einen Bildinhalt handelt es sich, ist er

  • informativ: wenigstens eine kurze Wiedergabe wesentlicher Informationen
  • dekorativ: leerer Alternativtext
  • funktional: Funktion des Links beschreiben, wohin führt der Link
  • Schriftgrafik: vermeiden, ansonsten Text wiedergeben
  • Komplexe Abbildung wie Diagramme: ausführliche Beschreibung, Datentabelle
  • Wichtige Informationsquellen

Grundlegende Syntax:

![caption](src "title"){fig-alt="Alternativtext"}

![Afrikanischer Buschelefant](assets/elephant.jpg "Elefant"){fig-alt="Afrikanischer Buschelefant auf einer Schotterpiste, die Ohren sind aufmerksam nach vorne gerichtet."}

Afrikanischer Buschelefant auf einer Schotterpiste, die Ohren sind aufmerksam nach vorne gerichtet.

Afrikanischer Buschelefant

Manuelle Alternativtexte für Diagramme

  • Alternativtext über Parameter für knitr-Codezellen: fig-alt
  • funktioniert mit Plots per graphics und ggplot2
#| fig-alt: Barplot, X-Achse zeigt die drei Arten Adelie (150 Exemplare), Chinstrap (63) und Gentoo (120)
species_count <- table(penguins$species)

barplot(species_count, main = "Häufigkeiten der Pinguinarten", 
        xlab = "Arten", ylab = "Häufigkeit")
Barplot, X-Achse zeigt die drei Arten Adelie (150 Exemplare), Chinstrap (63) und Gentoo (120)

Komplexe Grafiken

#| fig-cap: Zusammenhang von Flügelspannweite und Körpergewicht
#| fig-alt: Streudiagramm, betitelt mit Flügelspannweite versus Gewicht der Pinguine. Auf der X-Achse ist die Flügelspannweite abgetragen, von 170 bis 230 mm. Auf der Y-Achse ist ist das Körpergewicht abgetragen, von 3000 bis 6000 Gramm, in Abständen von 500 Gramm. Das Diagramm hat ungefähr 250 Einzelpunkte, die in einem Bereich von links unten nach rechts oben aufgetragen sind. Die Punkte für die drei Arten unterscheiden sich farblich, Rot für Adelie, Grün für Chinstrap und Blau für Gentoo. Die Punkte für die beiden Arten Adelie und Chinstrap konzentrieren sich im Bereich links unten bis ungefähr zur Mitte. Die Punkte für die Art Gentoo verteilt sich von der Mitte bis in die rechte obere Ecke.

ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g, color = species)) ...
Streudiagramm, betitelt mit Flügelspannweite versus Gewicht der Pinguine. Auf der X-Achse ist die Flügelspannweite abgetragen, von 170 bis 230 mm. Auf der Y-Achse ist ist das Körpergewicht abgetragen, von 3000 bis 6000 Gramm, in Abständen von 500 Gramm. Das Diagramm hat ungefähr 250 Einzelpunkte, die in einem Bereich von links unten nach rechts oben aufgetragen sind. Die Punkte für die drei Arten unterscheiden sich farblich, Rot für Adelie, Grün für Chinstrap und Blau für Gentoo. Die Punkte für die beiden Arten Adelie und Chinstrap konzentrieren sich im Bereich links unten bis ungefähr zur Mitte. Die Punkte für die Art Gentoo verteilt sich von der Mitte bis in die rechte obere Ecke.

Zusammenhang von Flügelspannweite und Körpergewicht

Alternativtexte mit BrailleR erstellen?

  • BrailleR erleichtert blinden Nutzenden die Arbeit mit R
  • momentan nur von GitHub installierbar
  • liefert unter anderem Details zu Diagrammen und Plots
  • Describe(): liefert nicht-kontextbezogene Informationen zu Grafikebenen eines Plots
  • VI(): extrahiert Details aus Plots oder anderen R-Objekten

A geom_point layer created with the ggplot2 framework

General Description:
A scatter plot shows the relationship between two variables by plotting a symbol for each observation at the coordinates for the two variables.

R hints:
A geom_point by default will by closed black dots. This can be changed with the `shape` parameter, while the size and colour can be changed with the `size` and `colour` parameter. These can be set to categorical variable to visually distinguish the groups 
This chart has title 'Flügelspannweite vs. Gewicht der Pinguine'.
It has x-axis 'Flügelspannweite (mm)' with labels 170, 180, 190, 200, 210, 220 and 230.
It has y-axis 'Gewicht (g)' with labels 3000, 4000, 5000 and 6000.
There is a legend indicating colour is used to show Pinguinarten, with 3 levels:
Adelie shown as strong reddish orange colour, 
Chinstrap shown as vivid yellowish green colour and 
Gentoo shown as brilliant blue colour.
The chart is a set of 342 big solid circle points of which about 85% can be seen.
It has size set to 3.

Alternativtexte mit KI erstellen?

Alternativtexte mit KI erstellen?

#| fig-alt: !expr ggplot2::get_alt_text(ggplot2_ai_alt)
1library(ellmer)

generate_alt_text = function(ggplot_obj) {
2  temp = tempdir()
  save_path = file.path(temp, "temp.png")
  ggsave (save_path, ggplot_obj)
1
Paket ellmer laden
2
Bild wird gespeichert, um es im LLM-Chat zu verwenden

Alternativtexte mit KI erstellen?

#| fig-alt: !expr ggplot2::get_alt_text(ggplot2_ai_alt)
1library(ellmer)

generate_alt_text = function(ggplot_obj) {
2  temp = tempdir()
  save_path = file.path(temp, "temp.png")
  ggsave (save_path, ggplot_obj)
3  alt_text_chat <- chat_openai_compatible(
    base_url = "https://api.yourllm.de/v1",
    credentials = function(){Sys.getenv("YOUR_API_KEY")},
    model = "Qwen3-VL-32B-Instruct-FP8"
  )
4  alt_Text = alt_text_chat$chat("Erzeuge einen kurzen und aussagekräftigen Alternativtext für das Diagramm für Menschen, die das Bild nicht sehen können. Beginne sofort mit dem Alt-Text ohne Text wie 'Alt-Text:' oder 'Beschreibung:' davor. Der Alt-Text soll zuerst den Diagrammtyp und die auf den Achsen aufgetragenen Variablen wiedergeben. Danach beschreibst du kurz und prägnant die wichtigsten in den Daten erkennbaren Muster oder Trends. Achte darauf, alle Wertebereiche in die Darstellung aufzunehmen, je genauer desto besser.", content_image_file(save_path))
}
1
Paket ellmer laden
2
Bild wird gespeichert, um es im LLM-Chat zu verwenden
3
LLM-Chat aufbauen
4
Beispiel für ein Prompt um Alt-Text zu erzeugen

Alternativtexte mit KI erstellen?

6#| fig-alt: !expr ggplot2::get_alt_text(ggplot2_ai_alt)
1library(ellmer)

generate_alt_text = function(ggplot_obj) {
2  temp = tempdir()
  save_path = file.path(temp, "temp.png")
  ggsave (save_path, ggplot_obj)
3  alt_text_chat <- chat_openai_compatible(
    base_url = "https://api.yourllm.de/v1",
    credentials = function(){Sys.getenv("YOUR_API_KEY")},
    model = "Qwen3-VL-32B-Instruct-FP8"
  )
4  alt_Text = alt_text_chat$chat("Erzeuge einen kurzen und aussagekräftigen Alternativtext für das Diagramm für Menschen, die das Bild nicht sehen können. Beginne sofort mit dem Alt-Text ohne Text wie 'Alt-Text:' oder 'Beschreibung:' davor. Der Alt-Text soll zuerst den Diagrammtyp und die auf den Achsen aufgetragenen Variablen wiedergeben. Danach beschreibst du kurz und prägnant die wichtigsten in den Daten erkennbaren Muster oder Trends. Achte darauf, alle Wertebereiche in die Darstellung aufzunehmen, je genauer desto besser.", content_image_file(save_path))
}

5new_alt_text <- generate_alt_text(ggplot2_cc_alt)
ggplot2_ai_alt <- ggplot2_cc_alt + labs(alt = new_alt_text)
ggplot2_ai_alt
1
Paket ellmer laden
2
Bild wird gespeichert, um es im LLM-Chat zu verwenden
3
LLM-Chat aufbauen
4
Beispiel für ein Prompt um Alt-Text zu erzeugen
5
Alternativtext generieren und per ggplot2::labs() anhängen
6
Plot mit Alternativtext ausgeben; der Alt-Text muss auch in den Chunk-Optionen eingebunden werden

Alternativtexte mit KI erstellen

Scatterplot mit Flügelspannweite (x-Achse, 170–230 mm) und Gewicht (y-Achse, 3000–6000 g) von drei Pinguinarten: Adelie (rosa), Chinstrap (grün), Gentoo (blau). Die Daten zeigen, dass Gentoo-Pinguine die größte Flügelspannweite (210–230 mm) und das höchste Gewicht (4500–6000 g) aufweisen. Chinstrap-Pinguine haben eine mittlere Flügelspannweite (180–210 mm) und ein Gewicht zwischen 3000 und 4500 g. Adelie-Pinguine zeigen die kleinste Flügelspannweite (170–195 mm) und das niedrigste Gewicht (3000–4500 g). Innerhalb jeder Art ist eine positive Korrelation zwischen Flügelspannweite und Gewicht erkennbar.

Der Alternativtext, den das LLM erzeugt hat:

Scatterplot mit Flügelspannweite (x-Achse, 170–230 mm) und Gewicht (y-Achse, 3000–6000 g) von drei Pinguinarten: Adelie (rosa), Chinstrap (grün), Gentoo (blau). Die Daten zeigen, dass Gentoo-Pinguine die größte Flügelspannweite (210–230 mm) und das höchste Gewicht (4500–6000 g) aufweisen. Chinstrap-Pinguine haben eine mittlere Flügelspannweite (180–210 mm) und ein Gewicht zwischen 3000 und 4500 g. Adelie-Pinguine zeigen die kleinste Flügelspannweite (170–195 mm) und das niedrigste Gewicht (3000–4500 g). Innerhalb jeder Art ist eine positive Korrelation zwischen Flügelspannweite und Gewicht erkennbar.

Haben wir was vergessen?

Welche Anforderungen werden nicht erfüllt?

  • Ausreichende Farbkontraste
  • Informationen nicht nur über Farbe vermitteln

Farbkontraste, Füllstile und Symbole

Beispiel: Farbkontraste und Symbole

Quelltext
ggplot_a11y <- ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g, shape = species, color = species)) +
  geom_point(size = 3) +  # Punktcharakter und Größe einstellen
  labs(title = "Flügelspannweite vs. Gewicht der Pinguine", 
       x = "Flügelspannweite (mm)", 
       y = "Gewicht (g)", 
       color = "Pinguinarten",
       shape = "Pinguinarten") +
  theme_minimal() +
  scale_color_brewer(palette = "Dark2")
ggplot_a11y
Streudiagramm, betitelt mit Flügelspannweite versus Gewicht der Pinguine. Auf der X-Achse ist die Flügelspannweite abgetragen, von 170 bis 230 mm. Auf der Y-Achse ist ist das Körpergewicht abgetragen, von 3000 bis 6000 Gramm, in Abständen von 500 Gramm. Das Diagramm hat ungefähr 250 Einzelpunkte, die in einem Bereich von links unten nach rechts oben aufgetragen sind. Die Punkte für die drei Arten unterscheiden sich farblich, Grün für Adelie, Orange für Chinstrap und Violett für Gentoo. Die Punkte für die beiden Arten Adelie und Chinstrap konzentrieren sich im Bereich links unten bis ungefähr zur Mitte. Die Punkte für die Art Gentoo verteilt sich von der Mitte bis in die rechte obere Ecke.

Zusammenhang von Flügelspannweite und Körpergewicht

Anforderungen an barrierefreie Datentabellen

  • Tabellenbeschriftung mit <caption> verfügbar
  • Spalten- und Zeilenüberschriften mit <th> ausgezeichnet, alternativ über ARIA-Rollen
  • keine leeren Zellen als Tabellenüberschrift
  • Bezüge zwischen Überschriften- und Datenzellen sind festgelegt, entweder per scope-Attribut oder per headers/id-Kombinationen
  • zusätzlich können Tabellenkopf und -fuß per <thead> und <tfoot> ausgezeichnet werden
  • das <summary>-Element darf in HTML5 nicht mehr genutzt werden

Wie gut erfüllten die Pakete flextable, gt, huxtable und kableExtra diese Anforderungen?

Einfache und komplexe Tabellen

Table GT: First rows of penguins dataset
Penguins dataset
species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g sex year
Adelie Torgersen 39.1 18.7 181 3750 male 2007
Adelie Torgersen 39.5 17.4 186 3800 female 2007
Adelie Torgersen 40.3 18.0 195 3250 female 2007
Adelie Torgersen NA NA NA NA NA 2007
Adelie Torgersen 36.7 19.3 193 3450 female 2007
Adelie Torgersen 39.3 20.6 190 3650 male 2007
Adelie Torgersen 38.9 17.8 181 3625 female 2007
Adelie Torgersen 39.2 19.6 195 4675 male 2007
Adelie Torgersen 34.1 18.1 193 3475 NA 2007
Adelie Torgersen 42.0 20.2 190 4250 NA 2007
Complex Table GT: Comparing bill and flipper by species and island
Bill and Flipper compared by Species and Island
bill
flipper
Species Island
length
depth
length
avg sd avg sd avg sd
Adelie Biscoe 38.97500 2.480916 18.37045 1.1888199 188.7955 6.729247
Adelie Dream 38.50179 2.465359 18.25179 1.1336171 189.7321 6.585083
Adelie Torgersen 38.95098 3.025318 18.42941 1.3394468 191.1961 6.232238
Chinstrap Dream 48.83382 3.339256 18.42059 1.1353951 195.8235 7.131894
Gentoo Biscoe 47.50488 3.081857 14.98211 0.9812198 217.1870 6.484976

Vergleich verschiedener Tabellen-Pakete

Kriterium Flextable GT Huxtable kableExtra
H51: Using table markup (table, tr, th, td) J J J J
H39: Using caption element N J J J
H63: Using the scope attribut N J N N
H43: Using id/headers attributes N J N N
Irregular headers marked via col, colgroup, colspan, rowspan J J J J
thead/tfoot only once per table J J J J

Empfehlung für Datentabellen: gt

Full-monty Accessibility

Tabelle
Vergleich der Flügellänge und Körpergewicht nach Pinguin-Spezies
Vergleich von Flügellänge und Körpergewicht
body
flipper
mass
Spezies
length
g
avg sd avg sd
Adelie 189.9536 6.539457 3700.662 458.5661
Chinstrap 195.8235 7.131894 3733.088 384.3351
Gentoo 217.1870 6.484976 5076.016 504.1162
Streudiagramm mit Flügelspannweite (in mm) auf der x-Achse (Bereich: 170–230 mm) und Gewicht (in g) auf der y-Achse (Bereich: 3000–6000 g). Drei Pinguinarten sind farblich und durch Symbole unterschieden: Adelie (grüne Kreise), Chinstrap (orange Dreiecke), Gentoo (lila Quadrate). Die Daten zeigen, dass Gentoo-Pinguine im Allgemeinen die größte Flügelspannweite (210–230 mm) und das höchste Gewicht (4800–6000 g) aufweisen. Chinstrap-Pinguine haben eine mittlere Flügelspannweite (180–210 mm) und ein Gewicht von etwa 3000–4200 g. Adelie-Pinguine weisen die kleinste Flügelspannweite (170–200 mm) und ein Gewicht von etwa 3000–4500 g auf. Es besteht eine positive Korrelation zwischen Flügelspannweite und Gewicht innerhalb jeder Art, wobei Gentoo-Pinguine bei gleicher Flügelspannweite deutlich schwerer sind als die anderen Arten.

Werkzeuge zur Prüfung

Wichtig: Eine automatische Prüfung allein ist nicht ausreichend!

Zusammenfassung

Machen Sie den “shift left” und berücksichtigen Sie die Barrierefreiheit von Anfang an!

  1. Ausgabeformat bewusst wählen
  2. Metadaten im YAML-Header setzen
  3. Dokument mit Überschriften gliedern
  4. Nicht-Textinhalte mit Alternativtext und Bildunterschrift versehen
  5. Farbgestaltung und Kontraste beachten
  6. Datentabellen barrierefrei mit dem gt-Package erstellen
  7. Barrierefreiheit überprüfen

Ich freue mich auf Ihre Fragen und Anregungen!