CSS Snippet
CSS clamp() — Fluid Typography
Text that scales smoothly between viewports. No jumps, no media queries, no guesswork.
Last updated: October 2026
Quick answer: clamp(min, preferred, max) sets a minimum size, a preferred size that scales with the viewport, and a maximum size. Use font-size: clamp(1rem, 0.5rem + 2vw, 2rem) for fluid typography. The browser interpolates every size in between — no breakpoints needed.
🎬 Interactive Live Demo
Drag the slider to simulate different viewport widths. Watch the text scale smoothly — no breakpoints, no jumps.
💡 Drag the slider from 320px to 1280px and watch the font sizes interpolate smoothly. No jumps.
The Problem: Breakpoint Jumps
Traditional responsive typography uses media queries:
h1 { font-size: 20px; }
@media (min-width: 768px) {
h1 { font-size: 32px; }
}
@media (min-width: 1200px) {
h1 { font-size: 48px; }
}
The problem: at 767px the font is 20px. At 768px it jumps to 32px — a 12px instant change. Users see a jarring resize as they drag the browser. And between breakpoints, the size is frozen — not tuned for the actual screen width.
The Solution: clamp()
h1 {
font-size: clamp(1.25rem, 1rem + 2vw, 3rem);
}
The three parts of clamp():
- Minimum:
1.25rem— the font never goes below this. - Preferred:
1rem + 2vw— the value the browser uses if possible. It scales with the viewport. - Maximum:
3rem— the font never goes above this.
Between the minimum and maximum, the browser interpolates every possible size. No jumps, no breakpoints.
How the Math Works
The preferred value mixes a fixed unit with a viewport unit. The vw unit means the size grows as the viewport grows:
/* At 320px viewport: */
1rem + 2vw = 16px + (2% of 320px) = 16px + 6.4px = 22.4px
/* But clamped to min 20px → 22.4px */
/* At 800px viewport: */
1rem + 2vw = 16px + 16px = 32px
/* At 1600px viewport: */
1rem + 2vw = 16px + 32px = 48px
/* But clamped to max 48px → 48px */
The clamp() ensures the font never renders outside its bounds, no matter how wide or narrow the viewport is.
A Complete Fluid Type Scale
Here's a production-ready scale that scales between a 360px phone and a 1280px desktop:
:root {
/* Body text: 16px → 18px */
--fs-body: clamp(1rem, 0.951rem + 0.217vw, 1.125rem);
/* H3: 20px → 28px */
--fs-h3: clamp(1.25rem, 1.054rem + 0.87vw, 1.75rem);
/* H2: 24px → 40px */
--fs-h2: clamp(1.5rem, 1.109rem + 1.739vw, 2.5rem);
/* H1: 32px → 64px */
--fs-h1: clamp(2rem, 1.217rem + 3.478vw, 4rem);
/* Section padding: 24px → 96px */
--space-section: clamp(1.5rem, -0.261rem + 7.826vw, 6rem);
}
body { font-size: var(--fs-body); }
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }
.section { padding-block: var(--space-section); }
Store each value as a custom property so it's defined once and referenced everywhere. This is the pattern used by production design systems.
clamp() for Spacing Too
clamp() isn't just for fonts. Use it for padding, margins, and gaps to create fluid spacing that scales with the viewport:
.section {
/* Padding scales from 24px to 96px */
padding-block: clamp(1.5rem, -0.261rem + 7.826vw, 6rem);
}
.container {
/* Container padding: 16px → 40px */
padding-inline: clamp(1rem, 0.5rem + 2vw, 2.5rem);
}
.card {
/* Card padding: 16px → 32px */
padding: clamp(1rem, 0.5rem + 1.5vw, 2rem);
}
Fluid spacing removes the need for media queries on section padding and container gutters. Fewer breakpoints, cleaner CSS.
🎯 clamp() vs Media Queries
| Aspect | clamp() | Media Queries |
|---|---|---|
| Behavior | Smooth interpolation | Sudden jumps at breakpoints |
| Code volume | One line per property | One block per breakpoint |
| Maintenance | Easy — one value | Hard — edit each breakpoint |
| Best for | Typography, spacing | Layout changes |
Rule of thumb: Use clamp() for anything that should scale smoothly (text, padding). Use media queries for layout that must switch abruptly (columns, sidebar visibility).
⚠️ Common Mistakes
- Using random vw values. If your text grows too fast, it becomes unreadable on large screens. Use a formula or tool to calculate the preferred value.
- Setting a minimum below 16px for body text. WCAG requires 200% zoom support. Body text should never go below 16px on any viewport.
- Using clamp() for layout changes. You can't switch from 1 column to 3 columns with clamp(). Use Grid's
auto-fitor media queries for that. - Forgetting the minimum. Without a minimum, clamp() allows text to shrink to unreadable sizes on very narrow viewports.
- Overusing clamp() everywhere. If a value doesn't need to scale, don't clamp it. Static values are simpler and faster.
- Using px in the preferred value. Use
remfor the fixed part of the preferred value so it respects the user's font-size preference.
❓ Frequently Asked Questions
What is clamp() in CSS?
clamp() is a CSS function that takes three values: a minimum, a preferred value, and a maximum. The browser uses the preferred value but never lets it go below the minimum or above the maximum. It's used for fluid typography and spacing.
How do I use clamp() for font sizes?
Use clamp(min, preferred, max) in font-size. For example: font-size: clamp(1rem, 0.5rem + 2vw, 2rem). The font grows with the viewport but stays between 1rem and 2rem.
Is clamp() supported in all browsers?
Yes. clamp() has been supported in all major browsers since 2020 and is part of the Baseline widely available set. It has over 96% browser support.
What is the difference between clamp() and calc()?
calc() performs math on units but doesn't enforce limits. clamp() is like calc() but with minimum and maximum bounds. Use clamp() for fluid typography and spacing where you need guaranteed limits.
Should I use clamp() or media queries for typography?
For most projects, use clamp() for typography. It eliminates the abrupt size jumps at breakpoints and reduces CSS. Use media queries for layout changes (columns, sidebar visibility), not for font sizing.