Skip to content

iOS Safari: #root { height: 100vh } puts the footer below the fold with no way to scroll to it #276

Description

@2ndtlmining

What

client/src/styles/_global.scss:83-88 pins the app to 100vh:

body { overflow: hidden; }

#root {
    min-width: 100vw;
    min-height: 100vh;
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}

.App { height: 100%; overflow: auto; }

On iOS Safari 100vh resolves to the large viewport — the height the page
would have if the URL bar and toolbar were hidden. With the browser chrome
actually on screen (the normal state on load) the real visible area is roughly
60–110 px shorter. So the bottom of #root sits below the fold.

Every escape hatch is closed:

  • body { overflow: hidden } — the page itself cannot scroll to reveal it.
  • #root { overflow: hidden } — same.
  • .App is height: 100% of a 100vh parent, so its own bottom edge — where
    the sticky footer lives — is off-screen too, and scrolling .App only moves
    its contents, never its bottom edge.

The result is the exact failure mode of #246: the footer is present in the DOM,
invisible, and unreachable by scrolling. #246 was fixed for the flex-shrink
cause (flex-shrink: 0 on .v-footer); this is the same symptom arriving by a
different route, and only on iOS.

Why this wasn't caught

Desktop Chrome has static browser chrome, so 100vh and the visible height are
identical and the bug cannot reproduce. I swept 320–1440 px in a real viewport
and found nothing here — the trigger is iOS's dynamic toolbar, not width.

Not confirmed on hardware. This is read from the CSS and from documented
iOS Safari viewport behaviour. It needs a real iPhone to verify, which is why
it is filed rather than fixed blind.

Fix

Progressive enhancement — browsers that don't know dvh ignore the second
declaration:

#root {
    height: 100vh;
    height: 100dvh;
    min-height: 100vh;
    min-height: 100dvh;
}

dvh tracks the dynamic viewport, shrinking and growing as the toolbar
slides. Supported in iOS Safari 15.4+ and every current desktop browser.

While here: width: 100vw includes the scrollbar gutter on desktop, which
forces a few px of horizontal overflow. width: 100% is the correct value and
costs nothing.

Acceptance

On a real iPhone, at first paint with the URL bar visible, the footer is
reachable by scrolling on /live (the tallest page) and /nodes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions