Viewport Units
Definition
There are four classic units. vw and vh are one per cent of the viewport width and height; vmin and vmax track whichever of the two is smaller or larger. Unlike a percentage, they ignore the parent element — height: 100vh is full screen height whatever it sits inside, whereas height: 100% only works if every ancestor has a height. They turn up as full-height hero sections and as spacing that grows on large screens, and they mix with fixed lengths through calc(), as in height: calc(100vh - 64px) to leave room for a header. They are not a substitute for a breakpoint: they scale smoothly with the window rather than switching a layout at a chosen width.
Why It Matters
The problem people actually hit is vh on a phone. Mobile browsers show and hide the address bar as you scroll, so the visible area changes by roughly 60 to 100 pixels, but 100vh is deliberately fixed to the larger measurement. A section set to 100vh is therefore taller than the screen when the bar is showing: a button pinned to the bottom sits below the fold, and the page scrolls by a hair when it should not. The newer units exist for this: dvh is the dynamic height, changing as the bar appears and disappears; svh is the small height, measured with the bar showing; lvh is the large height, with it hidden. Using 100dvh, or 100svh where nothing should ever be cut off, removes the problem outright.
How It Works
The browser resolves viewport units against the layout viewport, recomputing on resize and on orientation change. The classic vh is pinned to the largest viewport, matching lvh, so it does not reflow while the address bar animates — stability was the trade-off and cut-off content is the price. The dynamic units work in current Chrome, Safari, Firefox and Edge; for anything older, write the fallback first and the newer unit after, since a browser that cannot parse height: 100dvh simply keeps the height: 100vh above it. One more trap: vw counts the vertical scrollbar, so width: 100vw on a scrolling page is a few pixels wider than the content area and adds a horizontal scrollbar. Use width: 100% for full-width blocks and keep vw for cases where the overflow is intended.
Real-World Example
A digital invitation at wren-and-sam.99helpers.site puts the date and the RSVP button in a hero styled height: 100vh. On an iPhone with the address bar showing, the button sits just under the fold and half the guests never see it without scrolling. Changing the declaration to 100dvh, with 100vh left above as the fallback, brings the button on screen at every stage of scrolling and needs no JavaScript.
Common Mistakes
- ✕Using 100vh for a mobile hero and pinning something important to its bottom — the address bar makes the real viewport shorter, so that element starts out below the fold
- ✕Setting width: 100vw on a page that scrolls vertically — vw counts the scrollbar, so the element is a few pixels wider than the viewport and adds a horizontal scrollbar
- ✕Sizing body text in vw alone — the text becomes unreadable at one end of the range or the other, where clamp() with a rem minimum and maximum keeps it sane
Related Terms
Media Query
A media query is a block of CSS that only applies when a condition about the device is true — most often a minimum or maximum viewport width. It is the mechanism behind responsive design, written as @media followed by the condition and a set of rules in braces.
Breakpoint
A breakpoint is the viewport width at which a layout changes — the number you put in a media query. The query is the mechanism; the breakpoint is the decision about where the design stops working and needs rearranging.
CSS Variable
A CSS variable, properly called a custom property, is a named value declared in a stylesheet and reused wherever it is needed. You write it as --brand-blue: #1d4ed8 and read it back with var(--brand-blue).
Responsive Design
Responsive design is building one page that adapts to whatever screen opens it, using flexible layout and CSS media queries, instead of maintaining separate mobile and desktop versions.
Cumulative Layout Shift
Cumulative Layout Shift measures how much the content of a page moves about while it is loading. A good score is 0.1 or below; anything above 0.25 counts as poor.
Put a file online in seconds
Drop in a document, an image, a page or a whole static website and share the link — free, with no build step and no server to set up.
Host a file free →