ScreenshotNeo

BlogGuides

CSS Viewport Units: A Practical Guide

Learn how CSS viewport units work, when to use svh, lvh, and dvh, and how to build full-height layouts that behave across screen sizes.

By the ScreenshotNeo team4 October 20266 min read

CSS viewport units size an element against the viewport of the document, not against its parent. Use svh when a section should fit the smaller viewport with browser controls expanded, lvh when it should target the largest viewport with those controls retracted, and dvh when it should track the current viewport. The legacy vh unit maps to lvh, so 100vh can extend below the visible area on a mobile browser while its controls are showing.

What viewport units measure

A viewport unit is a percentage of a viewport dimension. For example, 1vw is one percent of the viewport width and 1vh is one percent of its height. It is not a percentage of the element’s parent. The viewport used is the one belonging to the document being styled; inside an iframe, that means the iframe’s viewport.

The unit families cover physical dimensions, writing-mode-aware dimensions, and the smaller or larger viewport dimension:

Unit family Meaning Example use
vw, vh Viewport width and height. A design explicitly tied to physical screen width or height.
vi, vb Viewport inline and block dimensions, following the writing mode. Layouts that should respect the text’s logical axes.
vmin, vmax The smaller or larger of viewport width and height. A size based on whichever viewport dimension is smaller or larger.
svw, svh, and related forms Small viewport dimensions. Fit content to the more constrained viewport state.
lvw, lvh, and related forms Large viewport dimensions. Size content for the largest viewport state.
dvw, dvh, and related forms Dynamic viewport dimensions. Track the current viewport as browser interface changes.

See the CSS Values and Units Module Level 4 and MDN’s CSS length reference for unit definitions and details.

Choosing between vh, svh, lvh, and dvh

Unit Viewport state represented Changes as browser controls move? Choose it when
svh Small viewport, with retractable browser interface expanded. No; it represents the constrained size. The section should fit within the smaller available viewport.
lvh Large viewport, with retractable browser interface retracted. No; it represents the maximum size. The design intentionally targets the largest available viewport.
dvh Current dynamic viewport. Yes; the value can change with the browser interface. The element should follow the currently available viewport height.
vh Large viewport height, equivalent to lvh. No; it retains the legacy large-viewport mapping. Existing behavior is intended, or compatibility with older styles is needed.

Mobile browser controls can retract or expand as a person scrolls. Since vh maps to the large viewport height, a 100vh element may be taller than the currently visible area while those controls are expanded. The specification says that mapping is presumed necessary for web compatibility.

Build a full-height section

For a content section that should be at least as tall as the constrained viewport but may grow when content needs more room, use a minimum height:

<main class="hero">
  <h1>A page that fits the screen</h1>
  <p>The section can still grow when its content needs space.</p>
</main>
.hero {
  min-height: 100svh;
  display: grid;
  align-content: center;
  padding: 2rem;
}

If the design should fill the viewport as it currently changes, use height: 100dvh. A fixed height can constrain content that needs more room, so consider overflow and content length before choosing it:

.viewport-panel {
  height: 100dvh;
  overflow: auto;
}

If the intended target is the maximum viewport, use min-height: 100lvh (or 100vh for the legacy equivalent). Pick based on the design’s behavior, then check it on target browsers while their controls expand and retract. These examples express unit semantics; the research for this guide does not include hands-on browser testing.

Use logical axes and min/max dimensions

Use vi and vb when sizing should follow the inline and block axes of the writing mode, rather than always meaning physical width and height. Use vmin or vmax when the smaller or larger viewport dimension is the intended reference. Their small, large, and dynamic counterparts follow the corresponding viewport-size interpretations.

.reading-measure {
  max-inline-size: 80vi;
}

.square-art {
  inline-size: 40vmin;
  block-size: 40vmin;
}

Logical units are useful when a layout should adapt to writing mode. If the design specifically means screen width or height, the physical vw and vh axes are clearer.

Common layout decisions and edge cases

  • Content may exceed one screen: prefer min-height so the section can grow. A fixed height needs a deliberate overflow strategy.
  • Mobile browser chrome is visible: choose svh to size to the constrained state, or dvh if the element should follow the current visible viewport.
  • The section should occupy the largest viewport: choose lvh; remember this can extend past the visible area while browser controls are expanded.
  • The page is embedded: viewport units refer to the iframe document’s viewport, not automatically the top-level browser viewport.
  • Width or writing direction matters: choose physical width/height or logical inline/block units to match the design’s intended axes.
  • The page has surrounding layout: viewport sizing is only one input. Padding, content size, overflow, and neighboring elements still affect the result.

Validate the result on target devices

  1. Choose the viewport state that matches the design goal: constrained, largest, or current.
  2. Use min-height for sections that should be able to grow; use fixed height only when the content and overflow behavior are intentional.
  3. Check the page at relevant device sizes, including while mobile browser controls expand and retract.
  4. Check long content and embedded contexts such as iframes if the page uses them.

CSS viewport units do not replace testing the layout’s actual content and surrounding structure. The appropriate unit depends on what the section should do when the viewport changes.

Or skip the browser setup

If you need an image of a page to review how a viewport-based layout renders, ScreenshotNeo returns a screenshot or PDF from one API request. See the API documentation for options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
  • Cookie banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
  • Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers identify the page verdict and billing status.
  • An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf.
  • 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo and get 1,000 free screenshots a month with no card.

Troubleshooting

Symptom Likely cause What to change
A 100vh section is clipped or taller than the visible phone area. vh maps to the large viewport height while browser controls may be expanded. Try min-height: 100svh for a constrained fit or height: 100dvh to track the current viewport.
Content disappears below a fixed-height panel. The chosen fixed height leaves no room for longer content. Use min-height for a section that can grow, or define appropriate scrolling with overflow.
A unit appears to size against an unexpected area in an embed. The styled document may be inside an iframe with its own viewport. Inspect the iframe’s dimensions and treat its viewport as the reference for that document.
A layout follows physical height when it should follow writing direction. vh expresses a physical axis. Consider vb or vi for block or inline sizing that follows the writing mode.
The viewport-fit result varies during scrolling. The chosen unit represents a different browser-interface state, or is dynamic. Decide whether the layout should fit the small viewport, fill the large one, or track the changing viewport; validate on target devices.

Performance, reliability, and cost

Viewport units are CSS length units; they do not require a screenshot service or API. A dynamic unit can change as browser controls move, so verify that the resulting layout behaves as intended during that transition. The research dossier provides no browser benchmark or cross-device test results, so performance differences should not be inferred from these examples. For visual review, a screenshot API can capture a rendered page, but a screenshot does not replace checking interactive behavior on the target device.

FAQ

Is 100vh always the visible height on mobile?

No. vh maps to the large viewport height, which can exceed the currently visible area when browser controls are expanded.

Should a hero use height or min-height?

Use min-height when content may need to make the hero taller than one viewport. Use a fixed height when the content and overflow behavior are controlled.

Do viewport units measure the parent element?

No. They refer to a dimension of the viewport belonging to the document being styled.

Which viewport units are writing-mode-aware?

vi and vb follow the inline and block axes; physical vw and vh refer to width and height.