/en/tool/clamp-generator/workscalculated in the browser
Set the size for a narrow and a wide screen, specify the widths between which it should grow, and get a clamp() expression instead of three media queries. You can also generate a complete scale: heading font sizes based on a modular ratio or a spacing set from 3xs to 3xl.
Between two widths, the size changes linearly; outside them, it hits the bounds.
Type-size pairs from a typical layout — click to fill them in
Layout width and the size at that width, separated by a colon; two pairs separated by a comma. Fills all four fields at once. Three pairs enable the breakpoint.
Lower bound: it will not get smaller than this
Upper bound: it will not get larger than this
Usually the narrowest phone you support
Usually the width of your container, not the monitor
Use this when the size should grow faster from phone to tablet than from tablet to desktop. The output uses min() or max() inside clamp().
Between the lower and upper widths
Between the lower and upper values
On phones, the scale is usually tighter: 1.2 reads better than 1.5
On desktop, the spacing between headings can be wider
Headings: six levels mean five steps up
Labels and footnotes: two are usually enough
The arithmetic based on the property stays the same — only its name in the final string changes
Only needed for conversion to rem
The sample, the current value, and the chart marker follow the slider: there is no need to drag the browser by its corner.
In your current window
—px
The accessibility check is included with the string.
Sample
This sample uses the same value
clamp.cssready-to-use CSS
—
clamp.tokens.jsondesign tokens
—
The browser does the calculation. No numbers or final strings are sent anywhere: the file is built right on your device, and the share link is stored in the address bar.
Chart and table
Horizontally, the width ranges from 320 to 2560 px; vertically, the size is shown in pixels. The flat sections on the left and right indicate that the value has reached a limit.
Take two sizes from the design: the phone size and the desktop size. The “Parse” button accepts them in a single string such as 375:20, 1440:48—the four fields will be filled in automatically.
Use the widths where the designs were created. Set the lower width to the narrowest supported screen and the upper width to the container width, not the monitor width.
Need all the typography at once? Switch to “Font size scale”: the base font size, the ratio on narrow and wide screens, and the number of steps up and down. The result is a set of --step--2 … --step-5 variables. “Spacing scale” works the same way and produces --space-3xs … --space-3xl and pairs such as --space-s-m.
Keep rem units: the rem term is required. A string containing only vw does not respond when the font size is increased in the browser settings. The “Accessibility” section shows how many times the text grows when the base font size is doubled and at 200% zoom.
The “Preview width” slider moves the entire view: the sample, the “Current” value, and the marker on the chart. The button next to it restores the actual viewport width.
The tabs below the code provide the same result in six formats: a CSS string, variables in :root, SCSS, PostCSS with separate min and max values, JSON tokens, and a Tailwind config snippet. The “Download file” button saves the selected tab.
The “Copy link” button puts the entire configuration into the URL. You can send the link in a chat, and your colleague will see the same scale.
clamp(min, slope × 100 vw + offset, max), where slope = (max − min) ÷ (max width − min width)
Slope — how many pixels the value grows for each pixel of viewport width
vw coefficient — the slope multiplied by 100: one vw unit is one percent of the viewport width
Offset — the value at zero viewport width: min − slope × min width
clamp — takes the middle value but keeps it within the limits set by the first and third arguments
Scale step — the base font size multiplied by the ratio to the power of the step number: 16 × 1.25³ = 31.25
Breakpoint — two lines instead of one; min() or max() inside clamp() determines which one is used
The middle clamp() argument is an ordinary value, not a separate mode: the browser recalculates it at every width and clips it to the limits. Media queries are not needed. A scale is calculated the same way; the output simply contains one string for each step. Each step has its own min and max values, while the widths are shared.
Example breakdown: from 16 px to 32 px between 400 px and 1200 px
The input data is the same as the default field values:
you can calculate it mentally and confirm that the tool is telling the truth.
Offset: 16 − 0.02 × 400 = 16 − 8 = 8 px. In rem, that is 8 ÷ 16 = 0.5rem.
rem limits: 16 ÷ 16 = 1rem and 32 ÷ 16 = 2rem.
Check at 400 px: 0.5rem is 8 px, 2vw is 8 px, and the sum is 16 px. Check at 1200 px: 8 + 24 = 32 px.
Accessibility at 1280 px. Normally, 8 + 25.6 = 33.6 px there, but the maximum clips it to 32. The reader sets the base font size to 32 px instead of 16, so all rem values double: 16 + 25.6 = 41.6 px, with a maximum of 64. It was 32 and is now 41.6—that is 130%, not 200%, so WCAG 1.4.4 is not met. The tool shows this value immediately: to reach double the size, increase the upper limit or reduce the vw portion.
font-size: clamp(1rem, 0.5rem + 2vw, 2rem);
Frequently asked questions
Why not simply write font-size: 4vw?
For two reasons. First, on a narrow screen, that font size becomes unreadably small, while on a wide screen it becomes absurdly large: there are no limits. Second, a size set only in vw does not respond when the user increases the font size in the browser settings—the user increases the font size, but the text does not change. The rem term inside clamp() solves this problem, and the “Accessibility” section shows exactly how much.
What does the accessibility check show?
Two values matter. The first is how many times the value increases when the reader sets the base font size twice as large. The second is what happens at 200% page zoom: the viewport in CSS pixels becomes half as wide, the vw portion stays the same in physical size, and the rem portion doubles. WCAG criterion 1.4.4 requires text to scale up to 200%. If the text has already reached its maximum at your width and the vw portion is large, it will not grow, and the calculator will tell you.
How is a scale different from a single value?
It calculates the same thing, but for all steps at once. You set the base font size on a narrow and a wide screen, along with the ratio—for example, 1.2 on a phone and 1.25 on a desktop. Step n equals the base font size multiplied by the ratio to the power of n, calculated separately for the narrow and wide widths. A standard clamp() is then built from those two values. The result is a set of variables, --step--2 … --step-5, which you add to :root once.
What is a spacing scale and what are pairs?
Nine steps from --space-3xs to --space-3xl: the base spacing multiplied by 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4, and 6. A pair such as --space-s-m takes the minimum from the smaller step and the maximum from the larger one: the spacing grows faster than the step and fits well into the vertical rhythm between blocks.
Why use cqi and cqw when vw is available?
vw units are based on the viewport, while cqi and cqw are based on the container with container-type: inline-size. If a block is in a narrow column on a wide screen, vw gives it a font size based on the monitor rather than the column. With container units, the “Preview width” slider means the container width, and the table and chart are calculated from it.
What does the intermediate breakpoint do?
It gives you two lines instead of one. From the lower width to the breakpoint, the size grows at one slope; after that, it grows at another. In CSS, this is written as min() or max() of two linear expressions inside clamp(): use min() when the first section is steeper than the second, and max() when the reverse is true.
What if the value should decrease instead of grow?
This can happen with letter-spacing: the larger the font size, the tighter the letters. Set a larger value on the narrow screen and a smaller one on the wide screen. The clamp() function requires its first argument to be no greater than its third; otherwise, it always returns the first argument. That is why the limits are swapped in the generated string. The calculator uses exactly the values you entered and tells you about the swap.
What if the lower width equals the upper width?
Then there is nothing to divide the slope by, so no line exists, and the calculator will tell you. You need a range, not a single point—otherwise this is an ordinary media query, not a fluid value.
Why use rem instead of px in the string?
So the size remains tied to the reader’s settings. Values in rem are multiplied by the reader’s base font size; values in px are not. You can switch units here, but rem is the default for a reason: with px, the accessibility check immediately shows 1 instead of 2.