Draw M3's focus ring on a dialog's scrolling body
Chrome makes a scroll container with nothing focusable inside a keyboard stop, and showModal() gives it the dialog's first focus, which showed the browser's own ring. The body now takes M3's 3px secondary indicator, inset so the dialog's rounded, overflow-hidden box does not clip it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Opus 5
parent
8a2d8c0327
commit
ff16b12b3b
@@ -56,3 +56,21 @@
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The scrolling body is a keyboard stop of its own when nothing inside it can take focus: Chrome
|
||||
* makes a scroll container focusable so the keyboard can scroll it, and `showModal()` hands it the
|
||||
* dialog's first focus. It then showed the browser's own ring. It takes M3's focus indicator
|
||||
* instead — 3px in secondary (tokens/state.css) — drawn inside its edge, because the dialog's
|
||||
* rounded, overflow-hidden box would clip a ring drawn 2px outside.
|
||||
*/
|
||||
@layer components {
|
||||
[data-dialog-body] {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
[data-dialog-body]:focus-visible {
|
||||
outline: 3px solid var(--md-sys-color-secondary);
|
||||
outline-offset: -3px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
@endif
|
||||
|
||||
@if ($body)
|
||||
<div id="{{ $id }}-body" x-dialog-dividers @class([
|
||||
<div id="{{ $id }}-body" data-dialog-body x-dialog-dividers @class([
|
||||
'min-h-0 flex-1 overflow-y-auto px-6 type-body-md text-on-surface-variant',
|
||||
'pt-2' => $header,
|
||||
'max-medium:pt-4' => $header && $barAboveBody,
|
||||
|
||||
Reference in New Issue
Block a user