As front-end developers, we must have encountered such a requirement: to implement a welcome page that occupies the entire screen, a pop-up mask, or a fixed bottom menu.
Intuition tells us that it's simple, just give it a height of 100vh.
Preview on PC, perfect! However, when you open it on your phone, you may see the following frustrating scene
Why does it exceed the screen height even though it is 100vh? Where did this annoying scrollbar come from?
If you have also scratched your head over this, congratulations, this article is your 'ultimate answer'. Today, I will thoroughly understand the pitfalls of 100vh on mobile devices and introduce you to the most perfect solution currently available.
To understand the essence of the problem, we first need to understand the definition of vh (Viewport Height) unit: 1vh is equal to 1% of the viewport height.
On the PC side, the browser window size is relatively fixed, so 100vh is the visible height of the browser window, which is not a problem.
But on the mobile end, the situation has become more complicated. In order to provide a better browsing experience in limited screen space, the address bar and bottom toolbar of mobile browsers (especially Safari and Chrome) are dynamically changing.
Initial state: When you first enter the page, the address bar and toolbar are fully displayed.
When scrolling: When you scroll down the page, these UI elements will automatically shrink or even hide to free up more space to display webpage content.
The key point is here: Most mobile browsers define 100vh as the "maximum viewport height," which is the height when the address bar and toolbar are fully collapsed.
This has led to:
When the page is initially loaded and the address bar is not collapsed, the actual calculated height of 100vh is greater than the height of the currently visible area of the screen.
So, the annoying scrollbar appeared.
For a long time, front-end developers could only rely on JavaScript to solve this problem. The idea is simple: obtain the height of the current visible viewport through windowinconerHeight, and then use it to dynamically set the height of the element.
JavaScript
![]()
Then use it in CSS as follows:
![]()
The drawbacks of this plan are obvious:
Performance overhead: Monitoring resize events too frequently may cause performance issues.
Logical coupling: A purely stylistic issue that requires JS to solve, not elegant enough.
Timing issue: The timing of performance needs to be precisely controlled, otherwise flickering may occur.
Although it can solve the problem, it is by no means the 'ultimate solution' we want.
Thank goodness, the CSS working group has heard our call! To address this long-standing issue, CSS Values and Units Module Level 4 has introduced a new set of dynamic viewport units.
They are our 'protagonists' today:
SVH (Small Viewport Height): The minimum viewport height. Corresponding to the visible height when the address bar and toolbar are fully unfolded.
LVH (Large Viewport Height): The maximum viewport height. Corresponding to the height when the address bar and toolbar are completely collapsed (which is actually equivalent to the old 100vh).
DVH (Dynamic Viewport Height): Dynamic viewport height. This is the most intelligent and practical unit! Its value will dynamically change with the appearance and disappearance of browser UI elements (address bar).
So, our ultimate solution is:
CSS
The copyright belongs to the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
![]()
Using 100dvh, when the address bar is collapsed, the element height will smoothly increase to fill the screen; When the address bar slides out, the element height will smoothly decrease again. The whole process is silky smooth without any scrollbars, perfect!
Browser compatibility
You may be concerned about compatibility issues. The good news is that starting from 2023, all mainstream modern browsers (Safari, Chrome, Edge, Firefox) will support these new viewport units.
It can be seen that compatibility is already very ideal. Unless you need to support very old browser versions, you can use them safely in production environments.
Let's quickly review:
Problem: On mobile devices, 100vh is usually parsed as "maximum viewport height", causing content overflow when the browser UI is not collapsed.
Old solution: Use JavaScript's window-INnerHeight for dynamic calculation, but there are performance and maintenance issues.
Ultimate solution: Use CSS's new dynamic viewport units, especially 100dvh, which can automatically adjust the height according to changes in the browser UI, perfectly solving the problem.
When it comes to achieving full screen layout on mobile devices, boldly bid farewell to 100vh and embrace 100dvh!