Skip to content

Size the DM screen with dvh so the composer stays on screen in a browser tab - #7

Open
eldrgeek wants to merge 1 commit into
PhilipRosedale:mainfrom
eldrgeek:fix/dm-composer-below-fold
Open

Size the DM screen with dvh so the composer stays on screen in a browser tab#7
eldrgeek wants to merge 1 commit into
PhilipRosedale:mainfrom
eldrgeek:fix/dm-composer-below-fold

Conversation

@eldrgeek

@eldrgeek eldrgeek commented Aug 3, 2026

Copy link
Copy Markdown

Symptom: in Chrome on a Pixel, the DM composer is off the bottom of the screen and unreachable. Installing the app to the home screen fixes it. That asymmetry is the whole diagnosis.

Cause: 100vh is the large viewport — the height with the URL bar retracted. In a browser tab with the URL bar actually showing, the visible area is ~56px shorter, so body.dm-screen-active .main-content runs past the bottom of the screen. The composer is the last item in that flex column, so it's what goes over the edge, and overflow: hidden means there's no scrolling to it. In standalone display mode there's no URL bar, so 100vh already equals the visible height — which is why it only reproduces in a tab.

Group chat mostly escapes this because layoutChatInputBar() re-pins .chat-input-bar from visualViewport measurements. The DM screen has no equivalent.

Fix: dvh, which tracks the viewport as browser chrome shows and hides. Both rules keep the vh line first as a fallback for older engines — the same pattern .globe-viz-wrap.expanded already uses:

height: calc(100vh - 180px);
height: calc(100dvh - 180px);

Two rules needed it: the base rule and the ≤480px override, which is the one that actually applies on a phone.

Verified on a Pixel in Chrome: composer unreachable before, fully visible after. 7 lines, CSS only.

Worth noting there are two other bare 100vh rules (styles.css lines 33 and 388) that may want the same treatment — I left them alone since they're min-height and I couldn't reproduce a problem with them.

…ser tab

In a mobile browser tab 100vh is the *large* viewport -- the height with the
URL bar retracted. With the URL bar actually showing, the visible area is
~56px shorter, so body.dm-screen-active .main-content runs past the bottom
of the screen. The composer is the last item in that column, so it is what
goes over the edge, and overflow:hidden means there is no way to scroll to
it. Reported on a Pixel in Chrome: the composer is not reachable.

Installing the app to the home screen fixes it, which is the tell -- in
standalone display mode there is no URL bar, so 100vh already equals the
visible height. It only reproduces in a browser tab.

dvh tracks the viewport as browser chrome shows and hides, which is what
this layout wants. Both rules keep the vh line first as the fallback for
older engines, the same pattern .globe-viz-wrap.expanded already uses.

Two rules needed it: the base one and the <=480px override, which is the
one that actually applies on a phone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@eldrgeek

eldrgeek commented Aug 3, 2026

Copy link
Copy Markdown
Author

If you want to see this on your own device before merging, here's a live repro that replicates the DM shell — an 80px fixed header, a viewport-sized flex column with overflow: hidden, and the composer as the last static item:

https://mw-safe-area-probe.netlify.app

Tap the vh/dvh button in the header to switch between the two. In vh mode with the URL bar showing, the readout prints how many pixels 100vh overflows the visible area — that number is exactly how far the composer is pushed off screen. In dvh mode it comes back.

Then add it to your home screen and reopen: in standalone mode there's no URL bar, so both modes look correct. That asymmetry is what made the diagnosis obvious.

(Scratch page of mine, not part of the PR — it'll go away once this is settled.)

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.

1 participant