Guide

← CSS Clamp Calculator

Buttons that grow up gracefully

One clamp() line for button padding, one for the font size, and the em trick that keeps the two in proportion. This is the recipe I reach for on every new project.

Here is the finished recipe, so you know where this ends up:

.btn { font-size: clamp(0.95rem, 0.95rem + 0.35vw, 1.15rem); padding: 0.7em 1.6em; min-height: 44px; border-radius: clamp(6px, 0.5rem + 0.4vw, 12px); }

That's it. Fluid type, padding in em so it tracks the type, a height floor for thumbs, and a corner radius that scales a little. Now the longer version, because the recipe hides three decisions that are worth understanding.

Why padding in em, not px

Fixed padding looks right at exactly one viewport. padding: 12px 28px on a phone gives a cramped-looking button; on a 1440px monitor the same button looks like a label with delusions of grandeur. The old fix was breakpoint padding. The new fix is fluid padding.

But the unit choice matters more than the fluidity. When the font-size is itself fluid, padding in em scales with the button's own type size, which keeps the visual proportions constant as everything grows. rem padding tracks the root font size instead, so it can drift out of proportion with the button text. px padding never moves at all, and then the type scales away from its own padding, which looks wrong at both ends.

There is one honest trade-off. If your button text wraps to two lines, em padding doesn't save you from a tall button, and the fixed min-height becomes the thing doing the layout work. That is fine. The two properties work together.

The touch target floor comes first

Before any clamp() line, decide the smallest your button is allowed to be. WCAG 2.2 Success Criterion 2.5.8 sets the AA bar at 24 by 24 CSS pixels for interactive targets. The 44px figure you see everywhere is the enhanced AAA criterion, a good aspiration but not the legal floor most teams are held to. I use 44px as a min-height for primary buttons anyway, because thumbs are bigger than the standard and nobody ever complained a button was too easy to tap.

This ordering matters because clamp() sets a minimum, not a guarantee. clamp(0.5rem, ..., ...) guarantees the padding is at least 0.5rem, but the rendered button height depends on font-size, line-height, and border width too. The min-height is the one declaration that enforces the floor directly. Set it, then tune the clamp.

Work the numbers for a real button

Take a primary CTA at a 16px root. On a 320px phone the font-size lands on the 0.95rem minimum (15.2px), the em padding computes to about 11px vertical and 24px horizontal, and the 44px min-height takes over to keep the whole thing tappable. At 768px the font-size reaches roughly 1.02rem (16.3px) with padding near 11px by 26px, so the button breathes without looking inflated. At 1440px the font-size hits its 1.15rem cap (18.4px) with padding around 13px by 29px, a confident CTA rather than a billboard.

The crossover math lives wherever you build the value. Our CSS Clamp Calculator with Tailwind export generates the exact clamp() line from your min and max, and the fluid spacing guide walks through the same technique for padding and gaps generally. If the button sits inside a component that has its own width, container query units beat viewport units for the preferred value.

One more thing you might not have considered, and you are forgiven for skimming past it: buttons that share a row need the same clamp. A primary and secondary button with different fluid values drift apart as the viewport grows, and nothing looks cheaper than two buttons that were clearly sized by two people. One shared .btn base, variants only for color.

The rule of thumb. Fluid font-size plus em padding plus a min-height floor. Set the min to your touch target floor, cap the max where the button stops looking like a button, and let the middle take care of itself. Generate the exact line in our CSS Clamp Calculator.

Frequently asked questions

What is a good clamp() for button padding?

A solid starting point is padding: clamp(0.5rem, 0.75rem + 0.5vw, 1rem) clamp(1rem, 1.25rem + 1vw, 1.75rem), with a clamped font-size alongside it. Tune the min and max against your type scale, and verify the rendered button never drops below a 24px touch target.

Should button padding be in em or rem inside clamp()?

Both work, but em padding scales with the button's own font-size, so the button keeps its proportions as the text grows. Rem padding stays tied to the root size. For buttons with fluid font-size, em usually looks better.

What is the minimum touch target size for buttons?

WCAG 2.2 Success Criterion 2.5.8 (Target Size Minimum, AA) requires interactive targets to be at least 24 by 24 CSS pixels. The older 44px figure comes from the enhanced AAA criterion 2.5.5. Your clamp() minimum should guarantee at least the 24px floor.

Can I use clamp() for button border-radius too?

Yes. border-radius: clamp(6px, 0.5rem + 0.4vw, 12px) scales the corner curve with the button. Keep it subtle: a radius that grows faster than the button looks melted.

Does fluid button padding work in all browsers?

clamp() is supported in all current browsers, so no fallback is needed for the function itself. If you support very old browsers, declare a fixed padding line above the clamp() line as the fallback.

Generate your own clamp() values

Dial in min and max sizes, preview the fluid scale live, and copy production-ready CSS.

Open the CSS Clamp Calculator

Prefer CSS tips by email? Subscribe to the newsletter.

Keep reading

Using CSS clamp() for Fluid Spacing: Padding, Margins, and Gaps That Scale Themselves

One clamp() line replaces the jump between breakpoints for padding, margins, and gaps, with the rule for what stays fixed.

CSS clamp() Fallbacks for Older Browsers: Two Methods That Work

Two fallback approaches for clamp(): the static declaration above, and the @supports not block. Plus the IE11 edge case that breaks the fancy one.

CSS clamp(), Finally Explained: Min, Preferred, and Max

How the browser resolves min, preferred, and max, with a worked fluid-type example and the rem accessibility rule.