8000 Add a viewport and make the two over-wide layouts usable on a phone by dhoelzer · Pull Request #36 · dhoelzer/DAD · GitHub
[go: up one dir, main page]

Skip to content

Add a viewport and make the two over-wide layouts usable on a phone - #36

Merged
dhoelzer merged 1 commit into
masterfrom
responsive-tables
Nov 11, 2026
Merged

dhoelzer merged 1 commit into
masterfrom
responsive-tables

Conversation

@dhoelzer
Copy link
Copy Markdown
Owner

What

Adds the missing viewport meta tag, and makes the two layouts that cannot fit a phone usable at narrow widths.

The tag

The layout emitted no viewport meta tag. Without it a phone renders the page at a ~980px virtual width and scales the result down - so any width-based CSS keys off a width the device does not have. Added width=device-width, initial-scale=1. Also added lang="en" to <html>, which the page had never declared.

Two layouts genuinely do not fit - and the numbers say so

Layout Required width Problem
Nav bar 19 tabs x 120px = 2280px #navbar ul sets overflow: hidden, so tabs past the edge are not wrapped and not reachable - they are clipped. An admin sees 10 of 19 tabs.
Alert queue 200 + 200 + 700 + 40 = 1140px display:table with fixed display:table-column widths. No phone is that wide.

Plus 16 index views using a plain <table>, and dashboard panels floated at 49% two-up.

The nav bar width is not a fixed number I picked: it is generated from $_models, which currently holds 19 models. Adding a model adds a nav tab.

Why this is verifiable without a browser

All narrow-screen rules go inside a single @media (max-width: 768px) block. That makes desktop rendering unchanged by construction rather than by inspection - which matters, because the rack-test system suite has no layout engine and cannot tell whether responsive CSS is correct.

Proven mechanically rather than asserted: the compiled bundle was split at the media query, and the portion outside it compared byte-for-byte against the previous build.

desktop portion byte-identical to previous build: True
  outside len: 8888   previous: 8888
media query bytes: 826 | selector collisions with the section that follows: []

The media query sits mid-bundle (byte 3249 of 9733), ahead of the CodeMirror section, and collides with none of its selectors.

Tables: one rule, not 16 templates

table { display: block; overflow-x: auto } keeps any sideways scroll inside the table rather than the page, and leaves thead/tbody/tr/td at their default table-* display so row structure is untouched.

white-space: nowrap - the third declaration this pattern usually carries - is deliberately omitted. Several of these tables have a description column, and nowrap forces one very long line per row, so it can produce a table far wider than the one it was meant to tame. Letting cells wrap cannot. The proper narrow-screen treatment (stacking each row into labelled blocks) needs a data-label on every cell, so it belongs with the view de-duplication rather than here.

No hamburger menu

Making the nav bar collapsible needs JS the app does not have. Letting the tabs wrap at 33% width makes all 19 reachable with no new behaviour - the smaller and more honest fix.

Guards added

The containment is the whole safety argument, so it is asserted in test/system/responsive_test.rb:

  • the viewport tag exists and carries width=device-width
  • nothing follows the @media block - a rule that falls out of it applies at every width and silently changes desktop rendering

Both checked against deliberate breakage:

Breakage Result
Appended #leaked { color: red; } after the block Expected "#leaked { color: red; }" to be empty. - fails
Deleted the viewport meta tag viewport test fails

Verification

Gate Result
rake test 437 runs / 1259 assertions / 0 failures / 0 errors
rake test:system 32 runs / 127 assertions / 0 failures (up from 30/120)
system tests, seeds 1 / 7 / 42 32 runs each, 0 failures
cucumber 5 scenarios / 18 steps passed
brakeman 0 warnings
bundle-audit no vulnerabilities
script/chec 8000 k_asset_paths.rb all 3 emitted asset paths on disk
production precompile CSS digest deterministic across two clean builds

Docs updated: RECOMMENDATIONS.md section 5.12, and AGENTS.md records the containment invariant plus the nav-bar/alert-queue widths so a future change does not undo them.

This PR was created by an AI agent (OpenHands) on behalf of the user.

The layout emitted no viewport meta tag, so a phone rendered every page at
a ~980px virtual width and scaled it down: width-based CSS keyed off a
width the device does not have. Added width=device-width, initial-scale=1,
plus lang="en" on <html>, which the page never declared.

Two layouts genuinely do not fit. The nav bar is generated from $_models:
19 tabs at 120px = 2280px, against a #navbar ul that sets overflow:hidden,
so tabs past the edge are clipped rather than wrapped -- an admin sees 10
of them. The alert queue is display:table with fixed table-column widths
summing to 1140px. Plus 16 index views using a plain <table>, and
dashboard panels floated 49% two-up.

All narrow-screen rules go inside one @media (max-width: 768px) block, so
desktop rendering is unchanged by construction rather than by inspection.
That matters because the rack-test suite has no layout engine and cannot
validate responsive CSS. Verified mechanically: split the compiled bundle
at the media query and the portion outside it is byte-identical to the
previous build (8888 bytes).

Tables are handled by one CSS rule rather than 16 templates. white-space:
nowrap is deliberately left out -- several tables have a description
column and nowrap would force one very long line per row.

No hamburger menu: that needs JS the app does not have. Wrapping the tabs
at 33% makes all 19 reachable with no new behaviour.

test/system/responsive_test.rb guards the containment (nothing may follow
the @media block) and the viewport tag. Both checked against deliberate
breakage: a leaked rule fails the first, deleting the tag fails the second.

Co-authored-by: openhands <openhands@all-hands.dev>
@dhoelzer
dhoelzer merged commit 4510aa8 into master Nov 11, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0