CSS Clamp

Tailwind CSS

How to use CSS clamp() in Tailwind CSS

Fluid font sizes and spacing in Tailwind CSS v4 and v3, from a quick arbitrary value to a full set of design tokens.

Tailwind CSS has no fluid utilities built in, but it does not need them. A clamp() value works anywhere Tailwind accepts a length. There are three ways to use one, from quickest to most maintainable.

All values on this page come from the clamp() generator. Set your sizes there and paste the result into any of the examples below.

1. Arbitrary values

For a one-off, put the value in square brackets. Leave out the spaces, because a class name cannot contain them. Tailwind adds them back around + and - when it generates the CSS.

<h1 class="text-[clamp(1.5rem,1.125rem+1.563vw,3rem)]">
    Fluid heading
</h1>

<section class="px-[clamp(1rem,0.25rem+3.125vw,4rem)]">
    Fluid page padding
</section>

Tailwind reads a value inside text-[…] as a font size when it looks like a length. If it ever picks the wrong type, add a hint: text-[length:clamp(1rem,0.5rem+2vw,3rem)].

Arbitrary values are fine for a single element. Once you use the same value twice, turn it into a theme token.

2. Theme tokens in Tailwind CSS v4

Tailwind CSS v4 is configured in CSS. Every variable in @theme with a known prefix becomes a set of utilities, and clamp() values work like any other value.

@import 'tailwindcss';

@theme {
    /* text-display, with its own line height */
    --text-display: clamp(2.25rem, 1.667rem + 2.593vw, 4rem);
    --text-display--line-height: 1.1;

    /* p-section, mx-section, gap-section, w-section, … */
    --spacing-section: clamp(1rem, 0.25rem + 3.125vw, 4rem);
}
<section class="px-section py-section">
    <h1 class="text-display">Fluid by default</h1>
</section>
  • --text-* creates font size utilities. --text-*--line-height pairs a line height with it.
  • --spacing-* creates padding, margin, gap, width, height and inset utilities with the same name.
  • You can also overwrite the default steps. Redefining --text-4xl makes every text-4xl in your project fluid. This site does exactly that for its whole type scale.

A complete fluid type scale

The examples page has a type scale for h1 to h6 and body text from 360px to 1440px. Drop it into @theme and you get text-h1 through text-p:

@theme {
    --text-h1: clamp(2.25rem, 1.667rem + 2.593vw, 4rem);
    --text-h2: clamp(1.875rem, 1.5rem + 1.667vw, 3rem);
    --text-h3: clamp(1.5rem, 1.25rem + 1.111vw, 2.25rem);
    --text-h4: clamp(1.25rem, 1.083rem + 0.741vw, 1.75rem);
    --text-h5: clamp(1.125rem, 1.042rem + 0.37vw, 1.375rem);
    --text-h6: clamp(1rem, 0.958rem + 0.185vw, 1.125rem);
    --text-p: clamp(1rem, 0.958rem + 0.185vw, 1.125rem);
}

3. tailwind.config.js in Tailwind CSS v3

In Tailwind CSS v3 the same tokens live in tailwind.config.js. A font size can be a string, or a tuple with a line height:

/** @type {import('tailwindcss').Config} */
module.exports = {
    theme: {
        extend: {
            fontSize: {
                display: ['clamp(2.25rem, 1.667rem + 2.593vw, 4rem)', { lineHeight: '1.1' }],
            },
            spacing: {
                section: 'clamp(1rem, 0.25rem + 3.125vw, 4rem)',
            },
        },
    },
};

That gives you the same text-display and p-section utilities as the v4 example.

Fluid values inside components

vw ties a value to the browser window. For a card that can sit in a narrow sidebar or a wide main column, scale with the container instead. Mark the parent with @container, which is built into Tailwind CSS v4, and swap vw for cqi:

<div class="@container">
    <article class="p-[clamp(1rem,0.25rem+3.125cqi,4rem)]">
        Padding that follows the container
    </article>
</div>

The deep dive explains how container units change the formula.

Plugins

If you would rather write a start and end size than a full clamp() value, a plugin like tailwind-clamp calculates the formula for you. The trade-off is another dependency, and output that is harder to read in your stylesheet. Plain theme tokens are usually enough.

Tips

  • Use rem for the bounds and the intercept, never only vw, so text still grows when users zoom in.
  • Use the same viewport range for every token, so all values grow in step. The generator lets you set it once.
  • Keep the number of tokens small. A handful of font sizes and two or three spacing values cover most sites.
  • Keep media queries, or Tailwind’s md: and lg: variants, for layout changes like switching from one column to three.

Tailwind CSS clamp() FAQ

Does Tailwind CSS support clamp()?

Yes. Tailwind has no built-in fluid utilities, but any clamp() value works as an arbitrary value, like text-[clamp(1rem,0.5rem+2vw,3rem)], or as a theme token. In Tailwind CSS v4 you add the token in @theme; in v3 you add it to tailwind.config.js.

How do I add a fluid font size in Tailwind CSS v4?

Add a --text-* variable with a clamp() value to @theme in your CSS, for example --text-display: clamp(2.25rem, 1.667rem + 2.593vw, 4rem). Tailwind then generates a text-display utility. Add --text-display--line-height to set a matching line height.

How do I use clamp() in Tailwind CSS v3?

Extend fontSize or spacing in tailwind.config.js, for example fontSize: { display: ["clamp(2.25rem, 1.667rem + 2.593vw, 4rem)", { lineHeight: "1.1" }] }. That creates text-display, and spacing entries create p-*, m-* and gap-* utilities.

Why does my arbitrary clamp() value not work in Tailwind?

Class names cannot contain spaces, so write the value without them: text-[clamp(1rem,0.5rem+2vw,3rem)]. Tailwind adds the spaces around + and - for you. If Tailwind treats the value as a colour, add a type hint: text-[length:clamp(1rem,0.5rem+2vw,3rem)].

Can I use clamp() with container queries in Tailwind?

Yes. Mark the parent with @container and use container query units instead of vw inside the value, for example p-[clamp(1rem,0.25rem+3.125cqi,4rem)]. The value then scales with the container instead of the whole window.