What is clamp() (CSS)?

clamp() (CSS): The CSS clamp() function picks a value between a minimum and a maximum from a preferred value in between, so one expression replaces several media queries.

clamp(min, preferred, max) returns the preferred value, unless it is smaller than the minimum or larger than the maximum, in which case it returns that bound. It is shorthand for max(min, min(preferred, max)). The preferred value is usually something that changes with the viewport or container, such as 5vw or 50%, and the bounds keep it sane. Because it works anywhere a length, number, angle or time is allowed, one line of clamp() can replace a stack of media queries for font sizes, spacing, column widths and more.

Examples

css
/* A readable column: at least 20rem, ideally 60% of the parent, never more than 70ch */
.prose { width: clamp(20rem, 60%, 70ch); }

/* Section spacing that breathes on wide screens */
.section { padding-block: clamp(2rem, 6vw, 6rem); }

/* A heading that scales with the viewport but keeps zoom working */
h1 { font-size: clamp(2rem, 1.2rem + 2.5vw, 4rem); }

/* A gap that follows the container */
.grid { gap: clamp(0.75rem, 2cqi, 2rem); }
  • Units can be mixed and math is allowed inside without calc(): clamp(1rem, 0.5rem + 2vw, 2rem) is valid as written.
  • If the minimum is larger than the maximum, the minimum wins. That can happen by accident when both come from variables.
  • Only one preferred value. For a curve with more than one segment, nest clamp() inside clamp(), or use min() and max() directly.
  • It works in custom properties, so a --space-section token can be fluid and every component that reads it inherits the behavior.

Accessibility

When the preferred value is a pure viewport unit, the result ignores browser zoom, because vw does not change when the user zooms the page. For text that fails WCAG 1.4.4, Resize Text. Always include a rem term in the preferred value for font sizes, and prefer rem-based bounds; fluid typography goes into the arithmetic. Spacing and widths have no such rule, but very large viewport-based padding on small screens still deserves a check at 320px.

In Tailwind CSS v4

Use an arbitrary value where the expression is a one-off, or define a token in @theme when it will be reused:

css
@theme {
  --spacing-section: clamp(3rem, 8vw, 8rem);
  --text-display: clamp(2.25rem, 1.5rem + 3vw, 4.5rem);
}
/* <section class="py-section"> and <h1 class="text-display"> */

Arbitrary values cannot contain spaces, so write the expression without them, py-[clamp(2rem,6vw,6rem)], or with underscores where a space is required, which Tailwind converts back: w-[clamp(20rem,_60%,_70ch)]. Container query units inside clamp() tie the value to the component's own width rather than the page.

In MiniDev

Layout primitives such as Container, Stack and Inset take fixed size steps so pages line up with the spacing scale, and clamp() belongs one level up, on section padding and display headings in marketing pages built with Hero and SectionHeader. Keep component internals on the scale and let the page breathe. The layout category lists the primitives.

ContaineruiResponsive page container that centers content with side padding and a max width preset: sm, default, lg or full. The basic wrapper for Tailwind layouts.npx shadcn@latest add @minidev/containerHerouiA centered landing page hero with an optional eyebrow, a large headline, supporting copy and up to two call to action buttons. A plain Tailwind starting point.npx shadcn@latest add @minidev/hero