{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "tabs-pfeiltasten-focusgroup",
 "name": "Tabs und Segmente mit Pfeiltasten",
 "name_en": "Keyboard tabs and segmented controls with focusgroup and roving tabindex",
 "kurz": "Reiter und Segmente sind eine Tab-Station: Pfeile, Pos1 und Ende wechseln innerhalb, nativ per focusgroup, sonst per roving tabindex.",
 "kategorie": "Zugang & Robustheit",
 "kategorie_slug": "zugang",
 "kategorie_nr": 17,
 "bau_chat": "E",
 "prioritaet": "E",
 "trendstatus": "aufsteigend",
 "belegstatus": "quellenbelegt",
 "website_belege": 0,
 "stimmung": [
  "präzise"
 ],
 "stimmung_roh": [
  "präzise",
  "funktional",
  "robust"
 ],
 "technik": [
  "focusgroup",
  "vanilla-js",
  "css",
  "aria"
 ],
 "technik_gruppen": [
  "css",
  "js",
  "andere"
 ],
 "leistungskosten": "niedrig",
 "steckbrief": {
  "beschreibung": "Tabs und Segment-Schalter sind für die Tastatur eine einzige Station: Tab springt hinein und wieder hinaus, die Pfeiltasten wechseln innerhalb, Pos1 und Ende springen zum ersten und letzten Eintrag. Seit Chrome 150 erledigt das HTML-Attribut focusgroup das Springen selbst, ohne Script. Für alle anderen Browser hält ein kleines Script den „roving tabindex“: nur der gewählte Tab hat tabindex=0, alle anderen -1. Rollen bleiben Pflicht: role=tablist, tab und tabpanel mit aria-selected und aria-controls. Zwei Arten der Aktivierung: automatisch (Auswahl folgt dem Fokus) oder manuell (Pfeile bewegen nur den Fokus, Enter oder Leertaste wählt). Segmente baut man am besten aus nativen Radios, die können Pfeiltasten von Haus aus.",
  "warum_es_wirkt": "Wer mit der Tastatur arbeitet, muss nicht durch jeden einzelnen Reiter tabben, um zum Inhalt zu kommen. Das Verhalten entspricht dem, was Screenreader-Nutzer von Desktop-Programmen kennen. Der gleitende Indikator zeigt die Auswahl, der Fokusring zeigt, wo man gerade ist; beides bleibt getrennt sichtbar.",
  "wann_einsetzen": "Funktions-Kapitel auf Produktseiten, Speisekarte mit Mittag, Abend und Getränke, Preise mit Monat und Jahr, Kursmodule, Einstellungsseiten mit senkrechten Reitern.",
  "wann_nicht": "Nicht für Navigation zwischen Seiten (dann Links in einem nav, keine Tabs). Nicht, wenn Nutzer Inhalte vergleichen müssen (dann untereinander zeigen). Automatische Aktivierung nicht, wenn das Panel erst lädt oder schwer ist; dann manuell. focusgroup nie ohne Fallback, solange nur Chromium es kann.",
  "varianten": [
   "Waagerechte Tabs, Auswahl folgt dem Fokus (automatisch)",
   "Waagerechte Tabs mit manueller Aktivierung über Enter oder Leertaste",
   "Senkrechte Tabs mit aria-orientation=vertical für Einstellungen und Funktions-Kapitel",
   "Segment-Schalter aus nativen Radios mit gleitender Pille",
   "Werkzeugleiste mit focusgroup=\"toolbar\""
  ],
  "umsetzung": "<div role=\"tablist\" aria-label=\"Funktionen\" focusgroup=\"tablist nomemory\"> mit <button role=\"tab\" id aria-selected aria-controls>, focusgroupstart am gewählten Tab; Panels <section role=\"tabpanel\" aria-labelledby tabindex=\"0\" hidden> (CSS: [role=tabpanel][hidden]{display:none}, sonst überschreibt display:grid das hidden). Erkennung: 'focusGroup' in HTMLElement.prototype. Nativ: keine tabindex-Werte an den Tabs (tabindex=-1 nimmt einen Tab aus der Gruppe). Fallback: gewählter Tab tabindex=0, andere -1; keydown auf der tablist: Pfeil vor/zurück mit Umlauf, Home, End, jeweils preventDefault und focus(). Automatisch: focusin auf einem Tab wählt ihn. Manuell: nur click wählt (Enter und Leertaste lösen bei button click aus). Wählen: aria-selected umschalten, Panels hidden umschalten, focusgroupstart bzw. tabindex=0 umziehen, Pille per translate und width (senkrecht: height) verschieben. Senkrecht: aria-orientation=\"vertical\" und focusgroup=\"tablist block wrap nomemory\". Segment: fieldset mit legend und nativen Radios (opacity 0 über dem Label), Fokusring am Label über :has(input:focus-visible), Pos1/Ende per keydown. Die Produktansicht ist eine figure mit figcaption, damit der Zeitraum-Schalter auch für Screenreader etwas Sichtbares ändert.",
  "mobil": "Waagerechte Tabs dürfen scrollen (overflow-x mit scroll-snap), der gewählte Tab wird ins Bild gerollt. Ziele mindestens 44 px hoch. Senkrechte Tabs werden auf dem Telefon zu waagerechten.",
  "reduzierte_bewegung": "Indikator springt ohne Gleiten, Panel erscheint ohne Weg.",
  "barrierefreiheit": "WCAG 2.1.1 Tastatur: alles per Tastatur bedienbar, Tab-Station je Gruppe. 2.4.3 Fokusreihenfolge: Tab landet auf dem gewählten Tab (focusgroupstart bzw. tabindex=0), dann im Panel. 2.4.7 Fokus sichtbar und getrennt von der Auswahl (Fokusring plus Pille). 2.4.11 Fokus nicht verdeckt: gewählten Tab in waagerechten Scroll-Leisten ins Bild rollen. 4.1.2 Name, Rolle, Wert: tablist mit Namen, tab mit aria-selected und aria-controls, tabpanel mit aria-labelledby; die Rollen gibt focusgroup nicht zuverlässig mit. 3.2.1 Bei Fokus: automatische Aktivierung zeigt nur Inhalt, sie wechselt keine Seite. 1.4.11 Kontraste: Pille und Fokusring mindestens 3 : 1. 2.5.8 Zielgröße mindestens 24 × 24 px, hier 44 px."
 },
 "messwerte": {
  "easing": "cubic-bezier(0.25, 0.46, 0.45, 0.94)",
  "dauer_ms": "Indikator 180, Panelwechsel 200, Farbe 120",
  "stagger_ms": "",
  "distanz": "Panel 6 px nach oben, opacity 0 → 1",
  "sonstiges": "Tempo der App wie im Rezept saas-produkt-praezise (Linear: easeOutQuad, .16–.18 s)",
  "herkunft": "eigene Festlegung",
  "quelle": "Rezept saas-produkt-praezise, bewegung"
 },
 "kurve": {
  "bezier": [
   0.25,
   0.46,
   0.45,
   0.94
  ],
  "css": "cubic-bezier(0.25, 0.46, 0.45, 0.94)",
  "name": "eigene Kurve",
  "dauer_ms": 180
 },
 "gesehen_bei": [
  {
   "seite": "Open UI: Focusgroup (Explainer)",
   "url": "https://open-ui.org/components/scoped-focusgroup.explainer",
   "auszeichnung": "",
   "beobachtung": "Syntax focusgroup=\"<verhalten> [inline|block] [wrap|nowrap] [nomemory]\", Verhalten toolbar, tablist, radiogroup, listbox, menu, menubar; tablist ist standardmäßig inline wrap. Die Gruppe wird zu einer Tab-Station, Pfeile und Pos1/Ende bewegen den Fokus. Auswahl ist entkoppelt: aria-selected, hidden der Panels und focusgroupstart setzt das eigene Script. Erkennung: 'focusGroup' in HTMLElement.prototype.",
   "art": "artikel"
  },
  {
   "seite": "Adrian Roselli: Focusgroup Tests",
   "url": "https://adrianroselli.com/2026/07/focusgroup-tests.html",
   "auszeichnung": "",
   "beobachtung": "Tests in Chrome 150 mit listbox, menu, menubar, radiogroup, tablist und toolbar. Rollen müssen trotzdem gesetzt und korrekt sein. Fallback für Browser ohne focusgroup nötig; native Elemente wie Radios bevorzugen. focusgroup=\"none\" soll Kinder aus der Pfeilnavigation nehmen, im Test blieben der Knopf und seine Nachbarn aber Tab-Stopps (vermutlich ein Bug). role=\"presentation\" oder role=\"none\" auf der Gruppe hat keine Wirkung, die Gruppenrolle bleibt. Pfeilachse folgt dem Standard-Layout der Rolle. Zweiachsige Navigation (Grids) ist zurückgestellt.",
   "art": "artikel"
  },
  {
   "seite": "W3C WAI-ARIA APG: Tabs mit automatischer Aktivierung",
   "url": "https://www.w3.org/WAI/ARIA/apg/patterns/tabs/examples/tabs-automatic/",
   "auszeichnung": "",
   "beobachtung": "Referenzbeispiel: roving tabindex, Pfeil links/rechts mit Umlauf, Pos1/Ende, Auswahl folgt dem Fokus. Panel mit tabindex=0, wenn es selbst nichts Fokussierbares enthält.",
   "art": "demo"
  },
  {
   "seite": "W3C WAI-ARIA APG: Tabs mit manueller Aktivierung",
   "url": "https://www.w3.org/WAI/ARIA/apg/patterns/tabs/examples/tabs-manual/",
   "auszeichnung": "",
   "beobachtung": "Pfeile bewegen nur den Fokus, Enter oder Leertaste aktiviert. Empfohlen, wenn das Anzeigen eines Panels spürbar dauert.",
   "art": "demo"
  }
 ],
 "tutorials": [
  {
   "titel": "Open UI: Focusgroup Explainer",
   "url": "https://open-ui.org/components/scoped-focusgroup.explainer"
  },
  {
   "titel": "W3C APG: Tabs Pattern",
   "url": "https://www.w3.org/WAI/ARIA/apg/patterns/tabs/"
  },
  {
   "titel": "Chrome Developers: Request for developer feedback: focusgroup",
   "url": "https://developer.chrome.com/blog/focusgroup-rfc"
  }
 ],
 "kombinierbar_mit": [
  "gleitender-indikator",
  "split-screen-sticky-seiten",
  "preis-section-editorial",
  "produkt-ui-hero-perspektiv-tilt",
  "akkordeon-hoehe-auto",
  "fokus-stil-system",
  "speisekarte-editorial"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/zugang/tabs-pfeiltasten-focusgroup/",
  "meta": "https://cecodesign.de/lab/fundus/zugang/tabs-pfeiltasten-focusgroup/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/zugang/tabs-pfeiltasten-focusgroup/demo"
 },
 "herkunft": {
  "quelldateien": [
   "DEF-Recherche 01.11.2026"
  ],
  "pruefnotizen": [
   "focusgroup in Chrome 150 laut DEF-Recherche (Release Notes 150) und Adrian Roselli (07/2026); Syntax aus dem Open-UI-Explainer, am 01.11.2026 per WebFetch gelesen. Am 02.11.2026 bestätigt: Chrome-Release-Notes 150 (stabil 30.06.2026) und Roselli-Test (05./14.07.2026). Andere Browser: kein Stand gefunden; focusgroup steht laut Roselli noch nicht in der WHATWG-HTML-Spezifikation, daher Fallback Pflicht.",
   "Headless-Prüfung lief mit Chromium 153; die Demo zeigt an, ob focusgroup nativ greift oder der Fallback.",
   "Keine Award-Website als Beleg; Muster ist Plattform-Standard (APG)."
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Reiter und Segmente sind eine Tab-Station: Pfeile, Pos1 und Ende wechseln innerhalb, nativ per focusgroup, sonst per roving tabindex.",
  "demo": true,
  "abhaengigkeiten": [],
  "werte": {
   "easing": "cubic-bezier(0.25, 0.46, 0.45, 0.94) (easeOutQuad, Rezept saas-produkt-praezise)",
   "pille_ms": 180,
   "panel_ms": 200,
   "panel_distanz": "translateY 6px → 0, opacity 0 → 1",
   "farbe_ms": 120,
   "fokusring": "outline 2px solid #5E6AD2, Versatz 2px (4,5 : 1 auf #FAFAFA)",
   "pille": "Weiß auf Spur #EFEFF1, Schatten 0 1px 2px rgba(22,22,22,.08) + 1px Kontur rgba(22,22,22,.06)",
   "ziele": "Tabs 40px (Touch 44px), Segment 36px (Touch 40px), min-width 64px",
   "focusgroup": "tablist nomemory (waagerecht), tablist block wrap nomemory (senkrecht), focusgroupstart am gewählten Tab",
   "erkennung": "'focusGroup' in HTMLElement.prototype",
   "fallback": "roving tabindex: gewählt 0, sonst -1; Pfeile mit Umlauf, Home/End",
   "segment": "fieldset mit nativen Radios, Pfeile von Haus aus, Pos1/Ende per keydown",
   "kontrastmodus": "@media (forced-colors: active): tablist und Segment-Spur 1px CanvasText, Pille 2px Highlight, gewählter Text Highlight",
   "grau": "#62666D (5,0 : 1 auf Spur #EFEFF1)"
  },
  "ausloeser": "klick",
  "touch": "Tippen wählt. Die waagerechte Leiste scrollt seitlich mit scroll-snap, der gewählte Tab wird ins Bild gerollt (nur die Leiste, nicht die Seite). Senkrechte Reiter werden unter 860 px waagerecht. Ziele 44 px.",
  "reduziert": "Pille springt ohne Gleiten, Panel erscheint ohne Weg, Leiste rollt ohne Glätten.",
  "korrekturen": {
   "umsetzung": "<div role=\"tablist\" aria-label=\"Funktionen\" focusgroup=\"tablist nomemory\"> mit <button role=\"tab\" id aria-selected aria-controls>, focusgroupstart am gewählten Tab; Panels <section role=\"tabpanel\" aria-labelledby tabindex=\"0\" hidden> (CSS: [role=tabpanel][hidden]{display:none}, sonst überschreibt display:grid das hidden). Erkennung: 'focusGroup' in HTMLElement.prototype. Nativ: keine tabindex-Werte an den Tabs (tabindex=-1 nimmt einen Tab aus der Gruppe). Fallback: gewählter Tab tabindex=0, andere -1; keydown auf der tablist: Pfeil vor/zurück mit Umlauf, Home, End, jeweils preventDefault und focus(). Automatisch: focusin auf einem Tab wählt ihn. Manuell: nur click wählt (Enter und Leertaste lösen bei button click aus). Wählen: aria-selected umschalten, Panels hidden umschalten, focusgroupstart bzw. tabindex=0 umziehen, Pille per translate und width (senkrecht: height) verschieben. Senkrecht: aria-orientation=\"vertical\" und focusgroup=\"tablist block wrap nomemory\". Segment: fieldset mit legend und nativen Radios (opacity 0 über dem Label), Fokusring am Label über :has(input:focus-visible), Pos1/Ende per keydown. Die Produktansicht ist eine figure mit figcaption, damit der Zeitraum-Schalter auch für Screenreader etwas Sichtbares ändert.",
   "varianten": [
    "Waagerechte Tabs, Auswahl folgt dem Fokus (automatisch)",
    "Waagerechte Tabs mit manueller Aktivierung über Enter oder Leertaste",
    "Senkrechte Tabs mit aria-orientation=vertical für Einstellungen und Funktions-Kapitel",
    "Segment-Schalter aus nativen Radios mit gleitender Pille",
    "Werkzeugleiste mit focusgroup=\"toolbar\""
   ]
  },
  "geprueft": "02.11.2026",
  "notiz": "Welt: Funktionsseite des erfundenen E-Rechnungs-Werkzeugs Siel aus Emden nach Rezept saas-produkt-praezise: Geist und Geist Mono, Graustufen auf #FAFAFA, ein Markenton #5E6AD2 für Fokus und Auswahl, Produkt-UI als dunkles HTML (#08090A, #161718, Statusfarben nur dort). Kapitel in Reihenfolge des Arbeitsablaufs (Erfassen, Prüfen, Melden, Archivieren), daneben ein Zeitraum-Segment aus nativen Radios. Ein Tastatur-Pult zeigt die gedrückte Taste und was passiert ist, dazu, ob focusgroup nativ greift (Chromium 153 im Test: ja) oder der Fallback; „Fallback erzwingen“ schaltet auf roving tabindex. Die Vorführung drückt gedachte Tasten (Tab, Pfeil, Ende, Pos1, bei Manuell Enter und Leertaste) und setzt dabei keinen echten Fokus. Referenzen: open-ui.org, adrianroselli.com, w3.org/WAI/ARIA/apg. AD-Review 02.11.2026: Note 4. Nachgebessert: inaktive Tabs und Segmente hatten 4,4 : 1, Grauton jetzt #62666D (5,0 : 1 auf #EFEFF1); Navigation auf dem Telefon als zweite Zeile statt versteckt; Kontrastmodus: Pille mit Highlight-Rand, Leisten mit Kante. Tastaturtest: Pfeile, Pos1, Ende und Umlauf korrekt, Tab verlässt die Leiste.",
  "varianten": [
   {
    "id": "auto",
    "name": "Automatisch",
    "wann": "Inhalte, die sofort da sind: Funktions-Kapitel auf Produktseiten, Speisekarte, Preise Monat/Jahr.",
    "werte": {
     "aktivierung": "focusin wählt",
     "focusgroup": "tablist nomemory",
     "achse": "Pfeil links/rechts"
    }
   },
   {
    "id": "manuell",
    "name": "Manuell",
    "wann": "Panels, die laden oder viel zeigen (Dashboards, Kartenansichten, Formulare im Panel): Pfeile bewegen nur den Fokus.",
    "werte": {
     "aktivierung": "click, Enter, Leertaste",
     "focusgroup": "tablist nomemory",
     "achse": "Pfeil links/rechts",
     "fokus_und_auswahl": "Fokusring und Pille getrennt sichtbar"
    }
   },
   {
    "id": "vertikal",
    "name": "Senkrecht",
    "wann": "Einstellungsseiten und Kapitel mit langen Namen in SaaS-Produkten; auf dem Telefon automatisch waagerecht.",
    "werte": {
     "aktivierung": "focusin wählt",
     "focusgroup": "tablist block wrap nomemory",
     "achse": "Pfeil hoch/runter",
     "aria_orientation": "vertical",
     "spalte_px": 220
    }
   }
  ]
 }
}
