Clamp Overview

For the longest time, I have always mistakenly thought that there’s some super-power in the clamp() function, that it “automatically” picks a best number based on min, max, and preferred value given (e.g. if we have clamp(10px, 15px, 20px), the value can be any value between 10px ~ 20px )

But the truth is that clamp doesn’t have ANY magics in it !

The clamp(MIN, PREFERRED, MAX); function is equivalent as: max(MIN, min(PREFERRED, MAX))

The “fluid” part actually comes from the relative units such as:

  • viewport-relative unit: clamp(100px, 10vw, 200px) (relative to the viewport’s width)
  • parent-relative unit: clamp(50px, 66%, 60px) (relative to parent’s width/height percentage)
  • font-relative unit: clamp(10px, 1.2em, 16px) (relative to the parent element’s font-size)
  • container-relative unit:clamp(30px, 10cqw, 70px) (relative to closest container)

The relative-parent will change depending on difference scenario, making the preferred value’s “absolute” value change with it, and this absolute value will be clamped by maximum and minimum threshold provided. (e.g font-size: clamp(10px, 0.5em, 15px), if parent font-size is within 20px ~ 30px (10px/0.5 ~ 15px/0.5) then the font-size will be 0.5rem; if the parent font-size is larger than 30px, the font-size will be 15px (upper-bound); if the parent font-size is smaller than 20px, than the font-size will be 10px (lower-bound).


More Example…

Example 1: Fluid Typography

Here’s a slightly more complicated example, of a <div> with a preferred value with combination both fixed and relative units in its min, max, and preferred value:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<textarea> ...                                               </textarea>
<style>    font-size: clamp(1rem, 2vw + 1rem, 100px);        </style>

             ⬇️
             
MIN:         1rem = 16px
MAX:         100px 
PREFERRED:   2vw + 1rem
               = (2 × 1% of viewport width) + 16
               = (2 × 12px) + 16   <----------------(assume 1200px for our viewport width)
               = 24 + 16           <----------------(since it is within 16px~100px range)
               = 40px 

2025-12-24T133331

Example 2: Fluid Decoration Box

Here’s an example of fluid card using container query "

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div class="card">
    <img src="https://picsum.photos/seed/1766545015367/600/300" alt="TEST">
    <div class="box"></div>
    <h2>Card title</h2>
    <p>
        This text scales based on the card width, not the viewport.
    </p>
</div>
<style>
    body{
        padding: 10px;
    }
    .card {
        container-type: inline-size; width: min(100%, 600px); padding: 0rem; border: 1px solid #ccc; border-radius: 10px; overflow: hidden;
        anchor-name: --card;
        .box  {width: clamp(20px, 50cqw, 300px);height: 10px;background-color: orange;position: absolute;position-anchor: --card;right: anchor(right);}
        img  {margin: 0px;width: 100%;}
        h2,p {padding-inline: 20px;}

        .box {width:     clamp(20px,     50cqw,             300px     ); }
        h2   {font-size: clamp( 1.25rem, 4cqw + 0.5rem,     2rem      ); }
        p    {font-size: clamp( 1rem,    2.5cqw + 0.25rem,  1.25rem   ); }
    }
</style>

2025-12-24T140656


Min-Max-Value Interpolation

If you want the unit (e.g. font-size) to adjust between certain two viewport sizes (e.g. the auto font-sizing magic from mobile to desktop), you can use this tool: “Min-Max-Value Interpolation” to preview and trial the values:

2025-12-24T134715


Reference

  • MDN Documentation - clamp(): link
  • Min-Max-Value Interpolation" tool: link
  • Solved by Modern CSS Section Layout - Ahmad Shadeed: link