Repository navigation
fix(frontend): stop pages scrolling horizontally at 1280, 768 and 390 - #767
Conversation
Tables scroll inside their own box at every width (the rule only applied below 768px), fieldsets get min-width: 0, hidden tooltips use display: none instead of visibility: hidden so they no longer extend the scrollable area, the recommendations action box and filter bar wrap, settings and inventory sub-tab bars scroll within themselves, a select inside a settings row stays within the row, and chart canvases are capped at their card width. A Playwright guard compares scrollWidth to the viewport for nine pages at three widths. Refs #703 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Warning Review limit reached
This review includes 6 billable files and costs up to $1.50.
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. Or wait 18 minutes for your next included review. View limit detailsLimit details: You’ve used the included review currently available. Your 85 included PR review attempts over the past 7 days set your current allowance at 1 review per hour. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (6)
Comment |
Independent review (rv-ux-visual): PR #767 at
|
| Page | 1280 base→head | 768 base→head | 390 base→head |
|---|---|---|---|
| Opportunities | 435 → 0 | 94 → 0 | 94 → 0 |
| Plans | 120 → 0 | 0 → 0 | 0 → 0 |
| Purchases | 153 → 0 | 0 → 0 | 0 → 0 |
| Admin General | 0 → 0 | 0 → 0 | 51 → 0 |
| Admin Purchasing | 0 → 0 | 1 → 0 | 379 → 0 |
| Admin Accounts | 0 → 0 | 66 → 0 | 444 → 0 |
| Admin Users | 0 → 0 | 8 → 0 | 386 → 118 |
Home and the three Inventory sub-tabs are 0 on both. Empty mode: everything is 0 on head except Admin Users at 390 (118).
Findings
- Medium (visual regression at desktop): tables no longer fill their card (
frontend/src/styles/responsive.css, new globaltable { display:block; max-width:100%; overflow-x:auto }).- With
display:block, the table element becomes the scroll box. The rows go into an anonymous table that is only as wide as its content, while the box keepswidth:100%, shadow and radius. - Seen at 1280:
- Admin → Accounts: the header background and row dividers of all three provider tables stop at about x=937, inside a card box that runs to x=1207. An empty white slab sits on the right of every table.
- Inventory → Coverage: the AWS rows end at about x=918 and the Azure rows at about x=900. The two tables no longer share column widths.
- Admin Users and the Admin Purchasing ladder tables change the same way (pixel diff bands).
- Before, these tables stretched edge to edge. This is the opposite of the "look top notch" goal, on every page with a short table.
- Fix: keep tables as
display: table; width: 100%and put the overflow on a wrapper:.table-wrap { overflow-x: auto; max-width: 100% }around each data table, oroverflow-x:autoon the existing table containers (#recommendations-list,#history-list, the coverage and accounts cards). Then a narrow table fills its card and a wide one scrolls inside it.
- With
- Medium: Admin Users at 390 still scrolls sideways by 118px, and the new guard cannot see it.
- The outermost offender is
div.group-card-actions(the "N members" badge plus Edit / Duplicate / Delete), 299px wide, with its right edge at x=508 on a 390 viewport..group-card-actions { display:flex; flex-shrink:0 }and.group-card-header { display:flex; justify-content:space-between }(settings.css) never wrap. - Fix:
.group-card-header { flex-wrap: wrap; gap: .5rem }and.group-card-actions { flex-wrap: wrap }. - Guard gap:
tests-e2e/fixtures/recs.tsmockApidoes not route/api/groups(nor/api/users), so/admin/usersrenders with no group cards inpage-overflow.spec.ts, and the 27/27 pass does not cover this. Add populated users and groups to the fixture, or to the spec, so the guard runs against real content.
- The outermost offender is
- Low (new axe violation):
scrollable-region-focusable(serious) on.permission-matrixat 390.- The matrix is read-only (no focusable cells). It is now a scroll container, so keyboard users cannot scroll to the hidden columns.
- The same rule already fires on base for the Inventory tables (from the old <768 rule), and this PR extends the pattern to all widths.
- Fix: give the scroll wrapper from finding 1
tabindex="0",role="region"and anaria-labelwhen it holds no focusable content. At minimum, do this for.permission-matrix.
- Nit: the tooltip's new
:focus-withintrigger is inert. None of the 10.info-iconspans inindex.htmlis focusable (notabindex, no focusable child), so keyboard users still cannot open them. Addtabindex="0"andaria-describedbypointing at the tooltip text, or leave the selector out until the icons are focusable.
Verified good
- The tooltip
visibility:hidden→display:nonechange, the.settings-category { min-width:0 }fieldset fix, the sub-tab rows that scroll in place, theselectcap, the wrapping Opportunities action bar and filter bar, and the canvasmax-widthall remove their offenders. The Opportunities action bar at 390 now wraps inside the viewport. - axe otherwise identical, or one node better on Opportunities
target-sizeand Admin Purchasingcolor-contrastat 390. No console errors. Home, and Plans/Purchases at 768/390, are pixel-identical.
Evidence (local, review host): /tmp/claude/ux-pr/shots-767/ (<page>-{base,head,head-empty}-{1280,768,390}.png, *-diff-*.png, axe-{base,head}.json, crop-acc-{base,head}.png, crop-cov-head.png). Offender finder: /tmp/claude/ux-run/overflow.js (BASE=… CASES=/admin/users:390).
… pages Tables keep display: table; the container that directly holds a table takes overflow-x: auto instead (the recommendations list is excluded so its sticky action box keeps sticking, its table scrolls itself). Group card actions and headers wrap, member pills break long emails, the permission matrix is a labelled focusable scroll region and is the containing block for its sr-only cell labels, and the dead tooltip :focus-within rule is dropped. The overflow guard now routes populated users and groups. Refs #703 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Independent review, round 2 (rv-ux-visual): PR #767 at
|
|
Merged (squash) at reviewed head 2b963b1 -> 9a14691. Reviewer: rv-ux-visual, approved round 2 at this SHA (comment names it). CI: 27/27 checks pass. Local (frontend, head archive): npm ci 0, tsc --noEmit 0, npm test 0 (99 suites, 3144 passed, 1 skipped), npm run lint 0 (0 errors, 125 pre-existing-style warnings). |
What
Removes page-level horizontal scroll (#703). Independent of #763/#764/#765 (branched from main e5ac75d). CSS plus one e2e guard.
Measured offenders on main with the mock API (outermost element past the viewport), all fixed:
display:block; overflow-x:autowrap only existed below 768px. Now global (responsive.css), so Opportunities (+439px at 1280), Purchases (+153), Plans (+30) no longer widen the page.<fieldset class="settings-category">:min-width: 0(Admin accounts/users/purchasing, up to +444px at 390)..info-icon .tooltip-textusedvisibility:hidden, which still extends the scrollable area; nowdisplay:none, shown on hover and:focus-within,max-width: calc(100vw - 2rem).flex-wrapandmin-heightinstead of a fixed 80px height; filter-status bar wraps (Columns button no longer at x=395 on a 390px screen)..settings-tabs/.inventory-subnavscroll within themselves; tab buttons don't shrink..setting-input selectis capped at the row width (a select sizes to its longest option; +181px on Admin purchasing at 390)..chart-section canvas { max-width: 100% }: the Home savings-by-service canvas drew 120px wider than its card in the e2e fixture.Not changed: scroll affordance and clipped right-edge columns inside tables (#185).
Refs #703 (VIS-09).
Verification
tests-e2e/page-overflow.spec.ts: 9 pages x 1280/768/390 assertscrollWidth - innerWidth <= 0. On a build of origin/main 10 of 27 fail (home x3, opportunities x3, admin general/purchasing/accounts/users at 390); on this head 27/27 pass./tmp/claude/ux-fixes/overflow.js): main shows hscroll 439/153/30/94/66/60/94/51/376/444/438 on 11 page/width combinations; this head shows 0 on all 27./tmp/claude/ux-fixes/shots/{home,opportunities,plans,purchases,inventory,admin-users,admin-general}-{main,pr3}-{1280,768,390}.png(e.g.opportunities-pr3-1280.png,admin-users-pr3-390.png). axecolor-contrastnode counts unchanged on every page.🤖 Generated with Claude Code