CSS Clamp() for responsive websites

Given the different viewports and screen sizes where users view webpages, ranging from mobiles, portable tablets to laptops and desktops, responsive websites are highly recommended in today's web design.

When it comes to flexibility and fluid layouts, it is essential to maintain control over the grid, widths, heights, images, etc. CSS functions like min(), max(), and media queries are some of the go-to functions that allow properties and elements to adjust to specific sizes within specific conditions and boost responsiveness.
To improve responsiveness and fluid breakpoints, developers are always looking for functions and properties that make it easier for them to write adaptable and responsive sites with the least possible code.
The evolution of CSS provides a new function called clamp(). This function allows us to declare a minimum value, a preferred value, and a maximum value in a single line of code.

To understand the clamp() correctly, we will first explore its predecessors - min() and max().

Min()

The min() function allows us to declare the smallest value from a list of comma-separated expressions as the value of a CSS property. The smallest declared value could also be a single expression.
When we set a min() value, the browser calculates the value and adjusts the property accordingly until it reaches the minimum value and then stops.

<DOCTYPE html> 
<html> 
  <body> 
    <p>This an example of min() with a minimum width of 200px</p> 
  </body> 
</html> 
*{ 
  box-sizing: border-box; 
} 
 
p{ 
  background: pink; 
  width: min(200px); 
  height: 100px; 
  padding: 20px; 
  margin:0 auto; 
  font-size: 15px;         
}

We set the minimum width here to 200px, and the width can never grow larger than this.

<DOCTYPE html> 
<html> 
  <body> 
    <p>This an example of min() with a minimum width of 50vw and 500px</p> 
  </body> 
</html> 
*{ 
  box-sizing: border-box; 
} 
 
p{ 
  background: pink; 
  width: min(50%, 500px); 
  height: 100px; 
  padding: 20px; 
  margin:0 auto; 
  font-size: 15px;         
}

In this example, the min-width is between 50% and 500px. The browser chooses between the two denotations based on the viewport. If it calculates that 50% is less than 500px, it uses ‘50%’ and ignores the ‘500px’. If by the browser’s calculation, 500px is less than 50% of the viewport at any point, it chooses to use 500px instead of the percentage value.

Max()

Max() is the opposite of min(). It takes one or more comma-separated expressions or values as its parameters. The largest value in a max() function is one the property adopts.
If we consider the same example as min().

width: max(50%, 500px)

The browser chooses either 50% or 500px as it is the maximum value.
Max() and Min() aren’t mutually exclusive. We can use them on the same element/property at the same time.

h1{ 
  background: pink; 
  height: 100px; 
  width: 300px; 
  min-width: 100px; 
  max-width: 500px; 
}

Clamp(): How does it work?

Min() and max() have served developers for years, but clamp() is a step-up in the business. According to MDN Web Docs,

The clamp() CSS function clamps a value between an upper and lower bound. clamp() enables selecting a middle value within a range of values between a defined minimum and maximum.
The clamp() function can be used anywhere a <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> is allowed.

Clamp() provides a more robust way of defining sizes, lengths, and widths with the addition of a preferred value. Rather than write the min() and max() values separately, we describe them on one line using clamp().

The syntax for clamp() is this: clamp(min, preferred value, max)

We declare the min value first, followed by the preferred value, and then the max value, in that order. Like the min() and max() functions, the minimum value is the smallest value we want to assign to the property – it cannot go below that value.
The maximum value is the largest value assigned to the element/property. The property cannot go over this maximum value no matter the viewing port or screen size.
The preferred value is a value in between the ‘max’ and ‘min’ values. We usually set it as a standard value.

Clamp() works under specific conditions defined by the ‘min,’ ‘max,’ and ‘preferred’ values. When we declare a clamp function, the browser adjusts and sets itself to the ‘min’ value if the preferred value is lower than the minimum value; it sets itself to the ‘max’ value if the preferred value is higher than the ‘max’ value.

The browser uses the preferred value if it is between the minimum and maximum value.
Let us look at the following examples.

Clamp with fonts

Adjusting fonts to match different screen sizes is quite tricky. If we set the font size to ‘24px’ on a desktop, it may look good. But on mobile, the text would be too big, and the users will find it challenging to comprehend the content.
With clamp(), we can set various values to move responsively between different viewports. So at a specific viewport, our text will be smaller or bigger, depending on screen sizes.

<html> 
<body>
  <div id="clampexample">
    <h1>Title Here</h1> 
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur</p> 
    </div>
</body> 
</html>
#clampexample{ 
  background: burlywood; 
  padding: 1rem; 
  width: 50vw; 
  margin:auto; 
} 

p{ 
  font-size:clamp(10px, 2vw, 18px); 
}

When we adjust the browser between screen sizes, we find that the text gets smaller as the browser contracts but never goes lower than 10px. Then it gets bigger as we expand, but never bigger than 18px since these are the declared values.

Clamp with widths

<html> 
<body> 
  <div id="clampexample"> 
    <h1>Title Here</h1> 
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur</p> 
  </div>
</body> 
</html> 
p{ 
  background: burlywood; 
  padding: 1rem; 
  width: clamp(100px, 50vw, 500px); 
  margin: auto; 
}

In the demo above, we set our paragraph width to 50vw of the browser. Our minimum value is 100px and max – 500px. As we expand and contract the browser, the paragraph’s width grows up to 500px and stops or contracts down to 100px and stops. Else, it just displays at 50vw.

Clamp() with Images

For web developers, controlling how images appear on a website and different media screens is part of a notorious struggle. Unlike text, images have fixed widths and heights. If not effectively managed, they may become blurry, overstretched, or too small with lots of surrounding spaces.
Using clamp() is an efficient way to manipulate and manage how images appear on various display sizes.
Before this useful function became available, we used to put images in ‘divs’ and then manipulate the ‘div’ to adjust the image position. With clamp(), we can now work directly on how images display, allowing us to be more flexible when positioning them, and we use less code while doing it.

Clamp() for Hero images

Hero images have a similar purpose as web banners. They usually take up 100% of the browser’s width. However, we can add constraints on these images, so they do not look too big or too contracted.

<html> 
  <body> 
    <img src="https://www.online-image-editor.com/styles/2019/images/power_girl.png" alt="girlonline">
  </body> 
</html> 
img{ 
  width: clamp(600px, 100%, 1400px) 
}

Clamp() for Image grids

Image grids are popular in web design, and with clamp(), we can set the max and min height to contain our images. Knowing exactly how people perceive the images we previously adjusted, we make a firm step toward achieving the ultimate customer experience. Our graphics should always be easy on the eye and a perfect fit for any screen size.
Our gallery will be created using a flexbox in addition to clamp()

<body> 
<ul class="imggallery"> 
  <li> 
    <img 
      src="https://cdn.searchenginejournal.com/wp-content/uploads/2019/07/the-essential-guide-to-using-images-legally-online-1520x800.png" 
      alt="" 
    /> 
  </li> 
  <li> 
    <img 
      src="https://www.online-image-editor.com/styles/2019/images/power_girl.png" 
      alt="" 
    /> 
  </li> 
  <li> 
    <img 
      src="https://cdn.searchenginejournal.com/wp-content/uploads/2019/07/the-essential-guide-to-using-images-legally-online-1520x800.png" 
      alt="" 
    /> 
  </li> 
  <li> 
    <img 
      src="https://www.online-image-editor.com/styles/2019/images/power_girl.png" 
      alt="" 
    /> 
  </li> 
  <li> 
    <img 
      src="https://www.online-image-editor.com/styles/2019/images/power_girl.png" 
      alt="" 
    /> 
  </li> 
</ul> 
</body> 
body { 
  margin: 0.5rem; 
  background-color: rgb(32, 19, 19); 
}
img { 
  object-fit: cover; 
  width: 100%; 
  height: 100%; 
}
.imggallery { 
  display: flex; 
  flex-wrap: wrap; 
  list-style: none; 
  padding: 0; 
  margin: 0; 
} 
.imggallery li { 
  flex: 1 1 15rem; 
  height: clamp(150px, 30vw, 500px); 
}

Floating/content images

Image galleries are just one of the many ways we can use to display images on responsive websites. A prevalent practice is arranging images side by side with some text around them.
We may need to maintain the same format on smaller screens. No need to have the image fill the whole screen with the text floating below it.

<html> 
  <body> 
    <div class="imgtext"> 
      <img src="https://www.online-image-editor.com/styles/2019/images/power_girl.png" alt="girlonline"> 
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
    </div> 
  </body> 
</html>
.imgtext img{ 
  float: left;
  width: clamp(200px, 50vw, 500px); 
}

In this example, we notice that the image maintains the same format, staying on the left side of the page while the text surrounds it. As the screen size gets smaller, so does the image, but not lower than 200px.

Clamp with CSS grid layout

CSS grid is a trendy grid layout. It is a two-dimensional layout that allows developers to arrange responsive content in rows and columns. CSS grid works primarily with a function called minmax().
We use this CSS function directly in the grid code to create dimensions and sizes for each template. It works just like the trusty min() and max() we just examined.
We can set grid templates like this: The minimum value is 150px, and the maximum - 25%. The next column gets a fraction. Example below:

display: grid;
grid-template-columns:  minmax(150px, 25%) 1fr;

Clamp() does not work on the grid-template-column, although that would be an exciting way to structure a grid. However, it does work on a grid-gap - the gutter between columns. With the columns and rows declared, we will use clamp() to control the spacing between them.

<body> 
  <div class="section"> 
    <div class="firstsection">
      This is the first column that is set to 150px and 25% 
    </div> 
    <div class="secondsection">
      This is the second column that is set to 1fr  
    </div> 
  </div> 
</body>
.section{ 
  display: grid; 
  grid-template-columns: minmax(150px, 25%) 1fr; 
  grid-template-rows: 300px; 
  grid-gap: clamp(5px, 2vw, 20px);   
}
.firstsection{ 
  background-color: cadetblue; 
  padding: 3em; 
}
.secondsection{ 
  background-color: rgb(177, 164, 116); 
  padding: 3em; 
}

Clamp() and Media Queries

Media queries and their respective breakpoints are the ultimate functions for responsive web designs. Using clamp() with media queries is a fantastic way to create smooth and fluid transitions between breakpoints since media queries breakpoints alone tend to be abrupt.

<body>
  <p>This is a new text</p>
</body>
@media screen AND (min-width: 400px) { 
  p{ 
    font-size: clamp(10px, 14px, 20px) 
  } 
}

Calc() with Clamp()

Min() and max() work extensively with calc(). The calc() allows us to perform value calculations. The result of these operations is the value of the expression.

width: calc(100% - 80px)

With clamp() and calc(), we can perform operations on comma-separated expressions using any of these four operators: addition, multiplication, subtraction, and division. We suggest nesting calc() within the clamp(), for optimum results.

<body> 
  <p>This is a a calc text</p>
</body>
p{
  font-size: clamp(12px, calc(0.54vw + 14px), 20px); 
}

In this demo, the calc() is performed on the preferred value. We can use calc() with clamp() on any of the units/values and maintain the same order of precedence: min value, preferred value, and max value.

Conclusion

The clamp() function can quickly become an efficient way of writing the ultimate responsive code. One of the biggest delights of clamp() is its influence across various elements and properties: fonts, widths, lengths, colors, media queries, etc. Clamp() can also be a crucial element in practical design solutions for fluid topography.
Clamp() popularity and ease of use naturally lead to significant browser support for it. In a short time, this function became part of all major browsers (except IE). We hope our practical overview of this clever function soon enhances your digital toolset.

Author

Ivaylo Ivanov

Ivaylo loves Frontend implementations. He is eager to construct interfaces that users love; pixel-perfect. In his day-to-day job, he caters to anything HTML, CSS, SCSS, or JavaScript-based on the frontend side. Complexity is not a problem, he masters VueStorefront implementations equally well to simple web apps or PWAs.
Experimentation with CSS and its' capabilities is Ivo's passion. Be it animated elements, or SVG animations - he loves it!