Stockio

CSS dvh vs vh (and svh, lvh): Fix Mobile Full Height

Choose modern viewport height units for mobile page shells. Compare dvh, svh, and lvh, preserve scrolling, and avoid clipped content when browser controls change.

By Jonah Weiss

Design Systems Lead ·

On this page

A page sized to one hundred viewport-height units can extend behind mobile browser controls or jump as those controls appear and disappear. Modern viewport units distinguish between small, large, and dynamic viewport sizes. Choosing the right one begins with deciding whether your layout should remain stable or track changing browser chrome.

Define what full height should mean

Use the CSS Clamp Calculator to establish bounded spacing for the shell, such as a gap that can grow without consuming the content area. The tool is useful for the space around the content; it does not determine which viewport unit matches the browser behavior you need.

Specify the height contract in plain language. A welcome screen may need to fit while browser controls are visible. A document shell may need to grow with content and merely fill the screen when content is short. A canvas application may deliberately maintain a bounded viewport-sized workspace.

Those are different requirements. Replacing every vh with dvh can make one page better and another visibly less stable. Select the sizing behavior per layout rather than treating the newest unit as a universal replacement.

Understand the three viewport sizes

Small viewport units use the viewport size associated with expanded browser interfaces. Large viewport units use the size associated with retracted interfaces. Dynamic viewport units vary with the current viewport size as browser interfaces change.

In a conventional horizontal writing mode, svh, lvh, and dvh express one percent of those respective heights. The small size is useful for stable visible space. The large size can fill the maximum area but may extend behind controls when those controls are present.

Dynamic units are useful when the layout should follow browser chrome. That can also cause visible resizing during scrolling. A hero whose content shifts while the address bar retracts may feel worse than one that deliberately keeps a stable minimum size.

Read MDN’s length reference for viewport unit definitions. Traditional vh is associated with the large viewport size in modern definitions, but historical implementations and browser-specific behavior are reasons to test the actual environments you support.

Prefer a minimum for document-like pages

A content page usually needs a minimum height rather than a fixed height. This lets the shell fill a short screen without clipping a long translation, enlarged text, or additional help content. Grid can reserve space for header and footer while allowing the main content to grow.

.page-shell {
min-block-size: 100vh;
min-block-size: 100svh;
display: grid;
grid-template-rows: auto 1fr auto;
}

.page-main {
padding: clamp(1rem, 3vw, 2.5rem);
}

.workspace {
block-size: 100vh;
block-size: 100dvh;
display: flex;
flex-direction: column;
}

.workspace__content {
flex: 1 1 auto;
min-block-size: 0;
overflow: auto;
}

The first layout is a growing document shell. The second deliberately bounds a workspace and gives its content region local scrolling. They should not be interchanged merely because both appear to fill the screen in a desktop screenshot.

The earlier vh declaration is a basic fallback for browsers that do not understand the newer unit. Unsupported declarations are ignored, leaving the earlier valid value in place. That fallback preserves an approximate layout, not identical mobile behavior.

Account for nested scrolling and safe areas

A bounded workspace needs an explicit scroll strategy. If the content region cannot shrink because of its automatic minimum size, it can overflow the workspace instead of becoming the intended scroller. That is why the example uses min-block-size: 0 on the flexible content region.

Avoid accidental double scrolling. Decide whether the document or an inner panel owns the main scroll. A fixed-height shell combined with page overflow and a separately scrolling content area can trap users in an awkward arrangement, especially when touch gestures begin over different panels.

Safe-area insets are another concern. On devices with display cutouts or home indicators, you may need padding that includes env(safe-area-inset-bottom). The viewport unit chooses a size; it does not automatically add all the spacing required around physical obstructions or system gesture areas.

MDN’s env() documentation explains the environment variables. Integrate them deliberately with your existing padding so one rule does not overwrite the other. A useful pattern combines ordinary spacing and an inset with calc() or chooses the larger value with max().

Test browser controls and keyboards separately

Do not assume a dynamic viewport unit solves every virtual keyboard issue. Keyboard behavior depends on browser policy, viewport configuration, and platform. The visible area and the layout viewport do not always resize in the same way when an input receives focus.

Test keyboard states explicitly: focus the first input, focus the last input, open a validation message, and dismiss the keyboard. Confirm that the focused control and its relevant action remain reachable without relying on a fixed screenshot of the initial page.

web.dev’s viewport unit article provides useful context for the newer units. Consult the existing responsive container guide when the surrounding inline sizing is also involved, but keep height behavior and width breakpoints conceptually separate.

Inspect portrait and landscape orientations, including a short landscape viewport with enlarged text. A fixed-height panel that looks generous in portrait can become unusable when a toolbar, footer, and keyboard consume most of the block axis.

Keep content escape routes intact. Essential text and actions should not be clipped merely to maintain a dramatic full-screen composition. Prefer a minimum height when the design does not genuinely require a bounded application workspace.

Record the chosen unit and its reason in your development documentation. “Use svh to avoid resizing while browser controls move” is actionable. “Use modern viewport units” is not. The explanation helps future maintainers preserve the behavior rather than replacing the value based on fashion.

Finally, inspect the fallback browser experience. A fallback can be slightly taller or shorter and still be acceptable if content remains reachable. The critical failure is inaccessible content or conflicting scroll regions, not a few pixels of difference in the initial composition.

Key takeaways

  • Choose stable small, maximum large, or current dynamic viewport sizing deliberately.
  • Prefer minimum heights for content pages that must grow.
  • Reserve fixed heights for workspaces with a clear scrolling model.
  • Treat safe areas and virtual keyboards as additional concerns.
  • Test changing browser controls, short landscapes, and long content.
Featured sponsor

Reach designers & developers at work

Put your product next to the tools people use every day. One sponsor per placement, no tracking pixels.

Become a sponsor

Keep reading

Related articles

More in HTML & CSS
HTML & CSS

Fluid Typography in Tailwind CSS With clamp()

Calculate fluid type scales, integrate clamp values into Tailwind, and test zoom and wrapping so headings resize smoothly without breaking layouts.

Includes: CSS clamp()Jonah WeissJonah Weiss
HTML & CSS

Responsive Spacing in CSS With clamp(), min() and max()

Build fluid gutters, section padding, and component gaps with CSS math functions, then test the boundaries without replacing every breakpoint with viewport units.

Includes: CSS clamp()Jonah WeissJonah Weiss
Typography & Colour

10 Best Coding Fonts: Monospace Picks for Developers

Compare ten dependable monospace fonts for code editors, terminals, and technical writing. Find options with ligatures, broad language support, or a clean familiar look, plus practical selection advice.

Includes: CSS clamp()Noor HaddadNoor Haddad
Typography & Colour

25 Best Free Google Fonts for Websites

Compare twenty-five useful Google Fonts for headlines, body copy, and interfaces, with practical notes on their character, readability, and where each works best on a website.

Includes: CSS clamp()Arjun RamanArjun Raman
AI for Design & UX

Chatbot UI Design: Chat Interface Patterns That Work

Design AI chat workspaces with clear context, readable responses, inspectable evidence and recovery controls that help users finish real tasks safely.

Includes: CSS clamp()Maya LindqvistMaya Lindqvist
AI for Design & UX

AI Personas and Synthetic Users: Where They Mislead

Use AI personas to challenge assumptions and rehearse research, without mistaking generated opinions for user evidence. Build a workflow that keeps real behaviour at the centre.

Includes: CSS clamp()Maya LindqvistMaya Lindqvist