Layouts switch at 16 different screen widths, so pages reflow in several steps #130

Closed
opened 2026-10-09 19:55:59 -04:00 by goddard · 1 comment
Collaborator

Each component picks its own screen width for switching to a narrower layout, so pages change in several separate steps as the window narrows instead of all at once. The app uses 16 different widths, and nothing tells a new component which one to use.

On the Servers page, narrowing the window from 1000 to 600 px changes the layout five times:

  • +page.svelte:1026 squashes the attention rows at 1000 px.
  • +layout.svelte:678 hides the sidebar at 960 px. +layout.svelte:118 repeats that width in JavaScript (min-width: 961px) to close the drawer.
  • +layout.svelte:708 tightens the top bar at 720 px.
  • ServerCard.svelte:449 shrinks the server cards' padding at 640 px.
  • +page.svelte:1034 shrinks the page summary and hides its metric link at 600 px.

Between those widths, the page is part desktop layout and part phone layout. Across src/, the 77 width media queries use 360, 440, 480, 500, 540, 600, 620, 640, 700, 720, 760, 800, 850, 960, 1000 and 1100 px. 640 and 600 account for 38 of them, and 500, 620, 700, 760 and 850 are used once each. docs/development/ui-patterns.md doesn't mention breakpoints.

CSS custom properties don't work inside @media, so a variable in tokens.css can't be used in the queries themselves. check-ui-styles.mjs already enforces the shared font sizes and can check widths the same way.

Fix

  • List the shared widths in tokens.css and ui-patterns.md, for example 360, 640, 960 and 1100 px
  • Move the app shell, Servers page and server cards onto those widths: 720 → 640 in +layout.svelte, and 1000 → 1100 and 600 → 640 in +page.svelte
  • Make check-ui-styles.mjs reject other widths in @media queries, with an allowlist of the files that haven't moved yet
Each component picks its own screen width for switching to a narrower layout, so pages change in several separate steps as the window narrows instead of all at once. The app uses 16 different widths, and nothing tells a new component which one to use. On the Servers page, narrowing the window from 1000 to 600 px changes the layout five times: - `+page.svelte:1026` squashes the attention rows at 1000 px. - `+layout.svelte:678` hides the sidebar at 960 px. `+layout.svelte:118` repeats that width in JavaScript (`min-width: 961px`) to close the drawer. - `+layout.svelte:708` tightens the top bar at 720 px. - `ServerCard.svelte:449` shrinks the server cards' padding at 640 px. - `+page.svelte:1034` shrinks the page summary and hides its metric link at 600 px. Between those widths, the page is part desktop layout and part phone layout. Across `src/`, the 77 width media queries use 360, 440, 480, 500, 540, 600, 620, 640, 700, 720, 760, 800, 850, 960, 1000 and 1100 px. 640 and 600 account for 38 of them, and 500, 620, 700, 760 and 850 are used once each. `docs/development/ui-patterns.md` doesn't mention breakpoints. CSS custom properties don't work inside `@media`, so a variable in `tokens.css` can't be used in the queries themselves. `check-ui-styles.mjs` already enforces the shared font sizes and can check widths the same way. **Fix** - [x] List the shared widths in `tokens.css` and `ui-patterns.md`, for example 360, 640, 960 and 1100 px - [x] Move the app shell, Servers page and server cards onto those widths: 720 → 640 in `+layout.svelte`, and 1000 → 1100 and 600 → 640 in `+page.svelte` - [x] Make `check-ui-styles.mjs` reject other widths in `@media` queries, with an allowlist of the files that haven't moved yet
goddard added the
priority
low
type/maintainability
labels 2026-10-09 19:55:59 -04:00
josh was assigned by goddard 2026-10-09 19:55:59 -04:00
goddard changed title from Layouts use 16 different breakpoints to Layouts switch at 16 different screen widths, so pages reflow in several steps 2026-10-09 23:38:44 -04:00
Author
Collaborator

Reviewed d2b2958700. All three fix items are done, so I'm closing this.

Checklist

  • List the shared widths. tokens.css:133-136 defines 360, 640, 960 and 1100 px, and ui-patterns.md:53 adds a "Responsive widths" section with what each is for and how to match them in JavaScript.
  • Move the app shell, Servers page and server cards.
    • +layout.svelte:709 moved from 720 to 640.
    • The drawer's JavaScript now uses the sidebar's own (max-width: 960px) query, inverted (+layout.svelte:119), instead of min-width: 961px.
    • +page.svelte:1022,1030 moved from 1000 to 1100 and from 600 to 640.
    • These three files now use only 360, 640, 960 and 1100 px (ServerCard.svelte was already on 640). Narrowing the Servers page from 1100 to 600 px now changes the layout at 1100, 960 and 640 px instead of at five widths.
  • Reject other widths in the style check. checkMediaWidths (check-ui-styles.mjs:61) reads the scale from tokens.css and rejects any other width, with an allowlist of 45 widths across 39 files (check-ui-styles.mjs:15). All 45 are still in use. I called it on sample queries:
    • In a new file, 640 px passes, and 700 px, 961 px and the 400 px side of a range query fail.
    • In the Leaderboard, its listed 800 px passes and 720 px fails.

Review notes

  • npm run check:styles passes and ui-style-check.test.js passes. Run 860 passed on this commit.
  • src/ still uses 16 widths in total, all from the allowlisted files. That's expected until they move; 600 px (15 uses) and 720 px (10) are the largest groups left.
Reviewed d2b29587000afff66019e0753c86ed7d82d2dee6. All three fix items are done, so I'm closing this. **Checklist** - [x] **List the shared widths.** `tokens.css:133-136` defines 360, 640, 960 and 1100 px, and `ui-patterns.md:53` adds a "Responsive widths" section with what each is for and how to match them in JavaScript. - [x] **Move the app shell, Servers page and server cards.** - `+layout.svelte:709` moved from 720 to 640. - The drawer's JavaScript now uses the sidebar's own `(max-width: 960px)` query, inverted (`+layout.svelte:119`), instead of `min-width: 961px`. - `+page.svelte:1022,1030` moved from 1000 to 1100 and from 600 to 640. - These three files now use only 360, 640, 960 and 1100 px (`ServerCard.svelte` was already on 640). Narrowing the Servers page from 1100 to 600 px now changes the layout at 1100, 960 and 640 px instead of at five widths. - [x] **Reject other widths in the style check.** `checkMediaWidths` (`check-ui-styles.mjs:61`) reads the scale from `tokens.css` and rejects any other width, with an allowlist of 45 widths across 39 files (`check-ui-styles.mjs:15`). All 45 are still in use. I called it on sample queries: - In a new file, 640 px passes, and 700 px, 961 px and the 400 px side of a range query fail. - In the Leaderboard, its listed 800 px passes and 720 px fails. **Review notes** - `npm run check:styles` passes and `ui-style-check.test.js` passes. [Run 860](https://gitea.thewrightserver.net/josh/electric-cherry/actions/runs/860) passed on this commit. - `src/` still uses 16 widths in total, all from the allowlisted files. That's expected until they move; 600 px (15 uses) and 720 px (10) are the largest groups left.
Sign in to join this conversation.