Bottom border not visible on 100vh element

Summary

A full‑height (100vh) container can unexpectedly hide its bottom border because the browser’s viewport height does not always equal the visible layout height. Mobile UI chrome, scrollbars, and fractional pixel rounding often push the bottom edge just outside the rendered area. Even with box-sizing: border-box, the border can fall below the fold.

Root Cause

The bottom border disappears because:

  • 100vh is not the true visible height on many devices, especially mobile browsers where the viewport height includes hidden UI chrome.
  • Scrollbars reduce the available layout height, causing the element to overflow by 1–2px.
  • Subpixel rounding can push the border just outside the visible region.
  • The wrapper inherits height: 100% from a parent already using 100vh, compounding the mismatch.

Why This Happens in Real Systems

Real browsers treat viewport height inconsistently:

  • Mobile browsers dynamically resize the viewport as toolbars appear/disappear.
  • Desktop browsers reserve space for scrollbars, reducing the actual renderable height.
  • CSS vh units are calculated before these adjustments.
  • Border thickness is added after layout calculations, so the border may overflow.

In short: 100vh is rarely the exact height you think it is.

Real-World Impact

This issue commonly causes:

  • Invisible bottom borders
  • Unexpected vertical scrollbars
  • Layout jitter on mobile
  • Off‑by‑one pixel gaps in full‑screen UI components (modals, hero sections, splash screens)

Example or Code (if necessary and relevant)

A reliable fix uses the newer dvh unit, which represents the dynamic viewport height:

.main-content {
  height: 100dvh;
  background-color: #000;
}

.wrapper {
  height: 100%;
  border: 1px solid red;
}

How Senior Engineers Fix It

Experienced engineers avoid 100vh for full‑height layouts and instead use:

  • 100dvh (dynamic viewport height)
  • 100svh (small viewport height)
  • 100lvh (large viewport height)
  • CSS logical viewport units to handle mobile UI chrome correctly
  • Avoiding nested 100% heights when the parent uses vh

They also test across:

  • Mobile Safari
  • Chrome with scrollbars
  • Devices with dynamic UI chrome

Why Juniors Miss It

Junior developers often assume:

  • 100vh equals the visible screen height (it doesn’t)
  • Borders are included cleanly with border-box (they are, but viewport math still breaks)
  • All browsers treat viewport units consistently (they don’t)
  • Scrollbars don’t affect layout height (they do)

They typically learn this only after debugging “invisible border” or “1px overflow” issues across devices.

Leave a Comment