CSS Clamp Calculator · Guides

The Hero That Stops Eating the Phone Screen

CSS clamp() for fluid hero section height is one min-height line that keeps a hero tall enough to impress and short enough to scroll past.

Published October 27, 2026

CSS clamp() for fluid hero section height solves a problem most developers meet twice: first on a laptop, where a 420 pixel hero looks lost on a tall monitor, and then on a phone, where a 100vh hero fills the whole screen and the visitor has to scroll before seeing anything else. A fixed height cannot serve both screens. A full viewport height serves neither one well, because phones and monitors do not agree on what a viewport is. One line of clamp() settles the argument by giving the hero a floor, a preferred height, and a ceiling.

The failure modes are worth naming, because each one points at a different wrong choice. A hero with height: 520px looks fine at one screen size and either cramped or empty at every other. A hero with height: 100vh looks dramatic on a desktop and broken on a phone, because mobile browsers measure 100vh against the full browser window, including the address bar area that hides and shows as you scroll, so the hero jumps and content slides under chrome. And a hero with height set at all has a third failure waiting: if the headline wraps to three lines on a narrow screen, or a translation runs long, the content overflows the fixed height and spills over whatever comes next.

Why min-height beats height for a hero

I reach for min-height, never height, for hero sections. Min-height guarantees the hero is at least as tall as you want, and it lets the section grow when the content needs more room. A long headline, a second button row, or a notice banner added by marketing will push the section taller instead of breaking it. Height does the opposite: it promises an exact size and breaks that promise the moment content disagrees. The one case where height makes sense is a hero with a fixed background treatment that must not move, and even there I would rather use min-height plus overflow control than a rigid box.

The viewport unit choice matters as much as the clamp() itself. The vh unit measures against the large viewport, which includes browser chrome that may not be visible. The svh unit measures the small viewport, the size when browser chrome is showing, and dvh tracks the dynamic viewport as chrome hides and shows. For a hero, svh is the steady choice: it will not jump during scroll. The safe pattern is a fallback line first, then the modern line, so older browsers get something sensible and modern ones get the better unit:

.hero {
  min-height: 520px;
  min-height: clamp(320px, 55svh, 640px);
}

Now the part I held back: the actual values. I use a floor of 320 pixels, a preferred value of 55svh, and a ceiling of 640 pixels. The floor is not arbitrary. A headline, a subline, and a button, with sane padding, need roughly 300 pixels before the section starts looking squeezed, so 320 leaves a little air. The ceiling keeps the hero from turning into a poster on a tall monitor. The preferred value, 55svh, means the hero takes just over half the visible screen, which leaves a hint of the next section peeking in, and that hint is what tells a visitor there is more below. Run the numbers: at an 800 pixel viewport height, 55svh is 440 pixels, inside the range, so the hero is 440 tall. At 1,400 pixels, 55svh is 770, capped to 640. At 500 pixels, 55svh is 275, floored to 320. Three screens, no breakpoints, no jumps.

CSS clamp() for fluid hero section height, with padding that scales too

A hero whose height scales while its padding stays fixed looks wrong at the extremes, so I scale the padding with the same trick: padding: clamp(1.5rem, 5vh, 4rem). The headline gets its own clamp() for font size, something like clamp(2rem, 5vw, 4rem). At that point the whole hero breathes with the viewport, and you have written zero media queries for it. If you want the hero to feel full height on a landing page and restrained on a content page, change only the preferred value: 80svh for the landing page, 45svh for the content page, same floor and ceiling. Use the CSS Clamp Calculator to generate your hero values and test the three screen sizes above before you ship.

Two cautions before you copy the snippet. First, do not put a full-bleed background image with critical text baked into it inside a clamped hero, because the crop changes as the height changes, and text baked into an image can slide out of frame at one end of the range. Keep text in HTML over the image. Second, older browsers that do not understand clamp() ignore the whole declaration, which is why the fallback min-height line sits above it. The fallback is not decoration. It is the version of the hero that a meaningful minority of visitors will actually see, so pick a fallback height you can live with, not a placeholder.

My opinion, briefly: the ceiling matters more than the floor. Developers obsess over the minimum, then ship heroes that are 900 pixels tall on desktop monitors because nobody capped them. A hero is an invitation, not the whole party. Cap it, let a strip of the next section show, and let the visitor decide to scroll.

Frequently asked questions

Should a hero use height or min-height with clamp()?

Min-height. It guarantees the hero is at least as tall as you want and lets the section grow when content needs more room. A fixed height clips long headlines and breaks when content is added later.

What viewport unit should the preferred value use?

svh is the steady choice for heroes, because it measures the small viewport with browser chrome showing and does not jump during scroll. dvh tracks the changing viewport, and vh can overstate the visible area on mobile.

Why does a 100vh hero look broken on phones?

Mobile browsers measure 100vh against the full window, including address bar space that hides and shows as you scroll. The hero jumps and content slides under the chrome. svh or dvh avoids that.

Does clamp() for hero height need media queries?

No. The floor, preferred value, and ceiling handle the whole range. Media queries still have a place for layout changes inside the hero, like stacking buttons, but not for the height itself.

What is the fallback for browsers without clamp() support?

Put a plain min-height line above the clamp() line. Browsers that do not understand clamp() ignore that declaration and use the fallback, so pick a fallback height you can live with.

Run your own numbers before you decide.

Use the CSS Clamp Calculator to generate your own fluid sidebar width and export it to Tailwind.

Related guides