#165: Reflow bei 320 px und Tastatur-Scrollbarkeit
Some checks failed
CI / Lint, typecheck, test (pull_request) Successful in 4m39s
CI / Build container images (pull_request) Successful in 4m2s
CI / Auth e2e pack (pull_request) Successful in 7m17s
CI / Import/export fidelity gate (pull_request) Successful in 56s
CD / Deploy to Test (push) Blocked by required conditions
CD / Smoke tests against Test (push) Blocked by required conditions
CD / Promote to Int (push) Blocked by required conditions
CI / Auth e2e pack (push) Blocked by required conditions
CI / Import/export fidelity gate (push) Blocked by required conditions
CI / Build container images (push) Blocked by required conditions
CD / Build and push images (push) Has been cancelled
CI / Lint, typecheck, test (push) Has been cancelled
Some checks failed
CI / Lint, typecheck, test (pull_request) Successful in 4m39s
CI / Build container images (pull_request) Successful in 4m2s
CI / Auth e2e pack (pull_request) Successful in 7m17s
CI / Import/export fidelity gate (pull_request) Successful in 56s
CD / Deploy to Test (push) Blocked by required conditions
CD / Smoke tests against Test (push) Blocked by required conditions
CD / Promote to Int (push) Blocked by required conditions
CI / Auth e2e pack (push) Blocked by required conditions
CI / Import/export fidelity gate (push) Blocked by required conditions
CI / Build container images (push) Blocked by required conditions
CD / Build and push images (push) Has been cancelled
CI / Lint, typecheck, test (push) Has been cancelled
Vier Ursachen des seitenweiten Horizontal-Scrollens behoben: die Topbar saß mit min-content-Breite in der Grid-Spalte (min-width: 0 nach dem #100-Muster) und wickelt auf schmalen Viewports auf eine zweite Zeile (Grid-Zeile minmax, Suchtext wird zum Icon); die aufgeklappte Sidebar liegt unter 40rem als Overlay über dem Inhalt statt ihn auf einen Streifen zu quetschen; Footer wickelt; Titel-Input und Settings-Spalte schrumpfen (min-width bzw. align-items: stretch im Schmal-Layout). Der Haupt-Scrollbereich ist per tabindex=0 tastatur-scrollbar — auf den Rechtstext-Seiten gab es sonst keinen Weg, den Inhalt zu scrollen. Gemessen: 10 Ansichten bei 320 px ohne Dokument-Überlauf (vorher 892 px Inhaltsbreite); e2e content/settings-nav/sidebar/legal/page-tree/search grün. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AGM8jo3hwoV9wsCVGfy8iq
This commit is contained in:
parent
057992faaf
commit
d4d4282c55
@ -64,7 +64,10 @@ export function AppLayout(): React.JSX.Element {
|
||||
<Sidebar collapsed={collapsed} />
|
||||
{!collapsed && <SidebarResizer widthRem={widthRem} onResize={setSidebarWidth} />}
|
||||
<div className="main-column">
|
||||
<main className="main">
|
||||
{/* tabIndex: the main area is the app's scroll container; on
|
||||
pages without focusable content (e.g. legal texts) keyboard
|
||||
users could otherwise not scroll it (#165, WCAG 2.1.1). */}
|
||||
<main className="main" tabIndex={0}>
|
||||
<Outlet />
|
||||
</main>
|
||||
{/* Outside the scroll container: always visible at the bottom
|
||||
|
||||
@ -96,7 +96,8 @@ export function TopBar({ sidebarCollapsed, onToggleSidebar }: TopBarProps): Reac
|
||||
onClick={() => setSearchOpen(true)}
|
||||
aria-label={t('search:open')}
|
||||
>
|
||||
<Search aria-hidden /> {t('search:open')}
|
||||
<Search aria-hidden />
|
||||
<span className="topbar__search-text">{t('search:open')}</span>
|
||||
</button>
|
||||
)}
|
||||
{searchOpen && user && <SearchPalette onClose={() => setSearchOpen(false)} />}
|
||||
|
||||
@ -53,7 +53,9 @@ button {
|
||||
/* Layout skeleton */
|
||||
.app {
|
||||
display: grid;
|
||||
grid-template-rows: var(--topbar-height) 1fr;
|
||||
/* minmax: the topbar row may grow when its controls wrap on narrow
|
||||
viewports (issue #165, WCAG 1.4.10). */
|
||||
grid-template-rows: minmax(var(--topbar-height), auto) 1fr;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@ -70,6 +72,10 @@ button {
|
||||
align-items: center;
|
||||
gap: var(--space-4);
|
||||
padding: 0 var(--space-4);
|
||||
/* Same #100 pattern as .app-body: without this the topbar's min-content
|
||||
width sizes the shared grid column and forces page-level horizontal
|
||||
scrolling on narrow viewports (issue #165, WCAG 1.4.10). */
|
||||
min-width: 0;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
background: var(--color-bg);
|
||||
/* Own stacking context above the scrolling `.main` content: the nav comes
|
||||
@ -91,6 +97,39 @@ button {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Narrow viewports (issue #165, WCAG 1.4.10): the topbar wraps onto a
|
||||
second row instead of pushing the page wider than the viewport; every
|
||||
control stays visible and reachable. The search button drops to its
|
||||
icon (the aria-label carries the name). The expanded sidebar becomes
|
||||
an overlay above the content — 256 px beside a 320 px viewport would
|
||||
leave the content a sliver and force page-level horizontal scrolling. */
|
||||
@media (max-width: 40rem) {
|
||||
.topbar {
|
||||
flex-wrap: wrap;
|
||||
row-gap: 0;
|
||||
padding: var(--space-1) var(--space-2);
|
||||
}
|
||||
|
||||
.topbar__search-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.app-body {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar:not(.sidebar--collapsed) {
|
||||
position: absolute;
|
||||
inset: 0 auto 0 0;
|
||||
z-index: 25;
|
||||
box-shadow: 2px 0 8px rgb(0 0 0 / 0.15);
|
||||
}
|
||||
|
||||
.sidebar-resizer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: var(--sidebar-width);
|
||||
flex-shrink: 0;
|
||||
@ -715,6 +754,9 @@ button {
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
flex-shrink: 0;
|
||||
/* Wrap instead of widening the page on narrow viewports (#165). */
|
||||
flex-wrap: wrap;
|
||||
min-width: 0;
|
||||
padding: var(--space-2) var(--space-8);
|
||||
border-top: 1px solid var(--color-border);
|
||||
background: var(--color-bg);
|
||||
@ -958,6 +1000,9 @@ button {
|
||||
|
||||
.editor-page__title {
|
||||
flex: 1;
|
||||
/* An input's intrinsic size-attribute width must not set the page's
|
||||
minimum width on narrow viewports (#165). */
|
||||
min-width: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
font-family: var(--font-heading);
|
||||
@ -3784,6 +3829,9 @@ ul[data-type='task_list'] li p:last-of-type {
|
||||
@media (max-width: 60rem) {
|
||||
.settings-layout {
|
||||
flex-direction: column;
|
||||
/* Override the row layout's flex-start: stacked, the content column
|
||||
must stretch to the viewport instead of its widest control (#165). */
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.settings-nav {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user