跪拜 Guibai
← All articles
Frontend

The 100vh Trap: Why Scrollable Pages Need `min-height`, Not `height`

By 陆枫Larry ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

This is a classic CSS gotcha that trips up developers of all levels, especially when building scrollable interfaces in frameworks like React, Vue, or any mobile environment. Understanding the difference between `height` and `min-height` is fundamental to creating layouts that behave predictably with dynamic content, and it directly impacts user experience by preventing visual glitches like missing backgrounds.

Summary

A developer debugging a WeChat Mini Program list page found that `height: 100vh` on the list container caused the background color to only fill the first screen. Scrolling down revealed a white background on the remaining items.

The root cause is that `100vh` is a fixed value equal to the viewport height. It does not account for content that exceeds one screen. The container is locked to that height, so any overflow content falls outside the container's background area.

The correct solution is `min-height: 100vh`. This sets a minimum height of one screen but allows the container to expand as content grows, ensuring the background fills the entire scrollable area. A secondary fix is to also set the background on the root `page` element as a fallback for edge cases like empty states or iOS rubber-band scrolling.

The article also clarifies why `height: 100%` doesn't work: percentage heights depend on the parent's height, which is often `auto` (content-driven), causing the child to collapse. Even if the entire parent chain is set to `100%`, it ultimately resolves to the viewport height, recreating the same fixed-height problem.

Takeaways
Setting `height: 100vh` on a scrollable container locks its height to the viewport, causing content overflow to appear without the container's background.
The correct fix for scrollable pages is `min-height: 100vh`, which ensures the container is at least one screen tall but can grow with its content.
Using `height: 100%` on a child element fails if the parent's height is `auto` (the default), as percentage heights are relative to the parent's explicit height.
Even if the entire parent chain is set to `height: 100%`, it ultimately resolves to the viewport height, recreating the same fixed-height problem as `100vh`.
For layouts with fixed headers and footers and a scrollable middle section, `height: 100vh` on the outer container is correct, combined with `overflow-y: auto` on the middle section.
In WeChat Mini Programs, the truly scrollable element is `page`, so setting the background on `page` provides a reliable fallback.
On mobile web (H5), `100vh` can include the browser's address bar, causing layout issues; `100dvh` (dynamic viewport height) is the modern solution, but this is not a concern in Mini Programs.
Conclusions

The real lesson is that CSS height properties are not interchangeable; choosing between `height` and `min-height` is a structural decision that depends entirely on whether the container should be fixed or flexible.

Many developers instinctively reach for `height: 100%` as a 'full-screen' solution, but this approach is fragile because it depends on an explicit height chain, which is often missing in real-world layouts.

The distinction between 'full-page scroll' and 'local scroll' is the most important architectural decision for layout. Using the wrong height property for the wrong scroll model is a common source of bugs.

The article's debugging process — from identifying the symptom, to understanding the unit, to testing alternatives, to finding the root cause — is a model for systematic CSS problem-solving.

The fact that this issue is common enough to warrant a detailed postmortem suggests that CSS layout fundamentals are still a pain point for many developers, even in modern frameworks.

Concepts & terms
100vh
A CSS unit representing 100% of the viewport height. It is a fixed value that does not change based on content length.
min-height: 100vh
A CSS property that sets a minimum height of 100% of the viewport, but allows the element to grow taller if its content requires more space.
Viewport
The visible area of a web page on a screen. Its dimensions are fixed at any given moment, but can change on resize or device rotation.
Content Height
The actual height of all content within an element, which can be much larger than the viewport, requiring scrolling to view.
Percentage Height (%)
A CSS height value calculated relative to the parent element's explicit height. If the parent has no explicit height (e.g., `auto`), percentage heights on children are invalid and collapse to `auto`.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗