dvh (Dynamic Viewport Height) is a modern CSS unit that adapts to the
currently visible height of the browser viewport. It sounds like a small detail,
but in practice it fixes a bug almost every web developer has run into.
If you've ever built a full-screen hero section and watched the browser's address bar cut off the bottom of it on mobile — or seen a stray scrollbar appear on a page designed to fit exactly one screen — this one's for you.
Why 100vh caused problems
By definition, vh is one percent of the viewport height. On desktop that's
unambiguous: the browser window's content area doesn't change as you scroll.
On mobile it does. The address bar and the bottom navigation controls collapse as you scroll
down and reappear as you scroll up, so the visible area is constantly moving. Browsers had to
decide what vh should mean in that situation, and most of them chose to
lock it to the largest possible value — the one you get once the browser chrome has
fully collapsed.
That had a few very visible consequences:
- a
height: 100vhsection extends below the screen on first load, - a layout designed to be exactly one screen tall becomes scrollable anyway,
- the button or scroll cue placed at the bottom of the hero slides out of view.
For years we worked around it: measure the real height in JavaScript, write it into a custom
property (--vh), then multiply it back with calc(). It worked, but it
solved a layout problem with runtime code.
The new family of viewport units
CSS no longer knows just one viewport height — it knows three, because on mobile there really are three sensible answers to the question "how big is the screen?"
svh(small viewport height) — the smallest visible height, i.e. when all the browser UI is showing.lvh(large viewport height) — the largest visible height, once the address bar and navigation have collapsed. This is what most browsers report asvh.dvh(dynamic viewport height) — the current value, which tracks the browser chrome as it moves.
So 100dvh isn't a fixed number — it's a live value, always equal to the space
that's genuinely available right now.
vhtells you how big the screen can be.dvhtells you how big it is.
The most common case: the hero section
The basic usage is exactly as simple as it looks:
.hero {
min-height: 100dvh;
}
There are two small but important details in those three lines. First, min-height
rather than height: if the content ever grows taller than one screen it flows on
instead of being clipped. Second, dvh already gives the correct result on its own
wherever it's supported.
If you still need to serve older browsers, the fallback is one extra line. CSS applies the last
declaration it understands, so a browser that doesn't know dvh simply skips the
second one:
.hero {
min-height: 100vh; /* older browsers */
min-height: 100dvh; /* everyone else */
}
No @supports, no JavaScript, no build step required.
Which one should you use?
dvh isn't a universal answer — it depends on what you're building. A simple way to
decide, which covers most cases:
dvh— when the element should fill the visible area and it's fine for its size to change: hero sections, full-screen slides, side drawers.svh— when the element must never overflow: fixed bottom bars, sticky CTAs, app-like mobile interfaces where the bottom button always has to be reachable.lvh— rarely needed, mostly when you're deliberately designing to the maximum height and overflow is acceptable.
A good rule of thumb: dvh for design, svh for guarantees.
If something must always be visible, don't leave it to the dynamic value.
Not just height
The same logic runs through all the viewport units, not only height. Each one gained an
s, l and d prefix:
dvw— dynamic viewport width,dvminanddvmax— the smaller and the larger of the two,dvianddvb— inline and block size, independent of writing mode.
In practice dvh is the reason the family exists — width changes far less often
mid-scroll on mobile.
What to watch out for
The strength of dvh is also its limitation: the value genuinely changes while you
scroll, and the browser has to re-run layout because of it.
Don't animate it
If a height expressed in dvh has a CSS transition on it, every movement of the
browser chrome kicks off an animation. The result is a jumpy, stuttering layout. Keep the size
change instant here.
Mind the content shift
If a 100dvh block sits in the middle of a long page, its height — and with it the
position of everything after it — moves as you scroll. Put full-screen sections near the top of
the page, or use svh further down.
The keyboard is a separate problem
On mobile, the on-screen keyboard isn't counted in the viewport height by every browser. If you
need a stable layout while a form field has focus, dvh alone won't get you there —
that's what the interactive-widget viewport setting or the Visual Viewport API is for.
Browser support
Dynamic viewport units have been supported by every major browser since Safari 15.4, Chrome 108,
Edge 108 and Firefox 101. In 2026 that effectively covers the entire active user base, and the
two-line vh fallback above takes care of the rest.
If you've been carrying a JavaScript --vh workaround, you can safely delete it:
the native unit is more accurate, faster, and doesn't flash before first paint.
Frequently asked questions
What is the difference between vh and dvh?
vh measures the viewport height, but on mobile browsers it doesn't follow the
address bar and navigation controls as they move — most browsers lock it to the largest possible
height. dvh adapts dynamically to the area that is actually visible, so it stays
accurate while you scroll.
When should I use dvh?
It's ideal for full-screen hero sections, landing pages, mobile web applications, and any layout
that should match the visible screen height. For fixed elements such as bottom bars or sticky
CTAs, svh is often the safer choice, because it never promises more room than there
really is.
Do modern browsers support dvh?
Yes. Modern versions of Chrome, Edge, Firefox and Safari all support the dvh unit.
For older browsers a simple vh fallback is enough: declare the vh rule
first, then the dvh one below it.