diff --git a/src/styles.css b/src/styles.css index 65ff1e3..3f268de 100644 --- a/src/styles.css +++ b/src/styles.css @@ -88,11 +88,13 @@ body { display: flex; flex-direction: column; align-items: center; - justify-content: center; + justify-content: safe center; gap: 18px; padding: 24px; text-align: center; z-index: 10; + overflow-y: auto; + overscroll-behavior: contain; } .overlay.green { background: var(--green); } diff --git a/src/ui/ambiguous-dialog.js b/src/ui/ambiguous-dialog.js index eeadd8f..761c039 100644 --- a/src/ui/ambiguous-dialog.js +++ b/src/ui/ambiguous-dialog.js @@ -38,6 +38,21 @@ export function askForStack(root, { spec, candidates }) { overlay.querySelector('#read').textContent = describeReading(spec); const choices = overlay.querySelector('#choices'); + + // Waehrend der Dialog offen ist, muss die Modalitaet, die per aria-modal + // behauptet wird, auch durchgesetzt werden: die Geschwisterelemente im + // Wurzelelement werden per inert unerreichbar (Tastatur, Zeigegeraet, + // Hilfsmittel). Elemente, die schon vorher inert waren, bleiben es - + // nur die selbst gesetzten inert-Markierungen werden spaeter entfernt. + const previouslyFocused = document.activeElement; + const madeInert = []; + for (const sibling of root.children) { + if (!sibling.hasAttribute('inert')) { + sibling.setAttribute('inert', ''); + madeInert.push(sibling); + } + } + root.appendChild(overlay); return new Promise((resolve) => { @@ -48,6 +63,20 @@ export function askForStack(root, { spec, candidates }) { if (settled) return; settled = true; overlay.remove(); + for (const sibling of madeInert) { + sibling.removeAttribute('inert'); + } + // Fokus darf nicht auf dem entfernten Dialog-Element haengen bleiben - + // zurueck zu dem, was vorher den Fokus hatte, sofern das noch moeglich ist. + if ( + previouslyFocused && + typeof previouslyFocused.focus === 'function' && + document.contains(previouslyFocused) + ) { + previouslyFocused.focus(); + } else { + root.focus?.(); + } resolve(result); };