Using clamp() instead of min() and max() in CSS

Week 300 was posted by Charanjit Chana on 2023-07-24.

It doesn't feel like it's been that long since I got my head around min() and max() functions in CSS.

min() is the minimum size something should be
... max() is the maximum size something should be

Its obvious really, but the word max just made me think that things would be big and that min would be the opposite. I did also look into minmax() but never got around to the clamp() function until recently.

In truth, I didn't dive deep enough into minmax() enough and couldn't tell you what it does but given I don't think I've ever seen it used in the while, I'll leave a deeper dive until later. Today though, I'll be taking a long overdue look at the clamp() function.

The arguments for clamp()

The clamp() function accepts three values, what I like to call atLeast, ideal and atMost. I referenced a video on typography last week and I'm linking to it again because it has really good use cases for when you'd use clamp. Both for sizing layouts and typography.

Typography, font-size and clamp()

I've started employing it more for SkeletonCSS, and you can see an example in the source code. I'm setting the minimum font-size for a page heading followed by the default font size + the 5vi units and then lastly the largest the font-size should be.

font-size: clamp(var(--font-size-xxl), 100% + 5vi, var(--font-size-xxxxl));

I've never really let my typography be as fluid as this, but it's simple and a no brainer as you scale up through screen sizes until you're happy with it's maximum size. Combined with max-width for content and layouts, it makes it all pretty harmonious without making a heading feel too small or too large on any screen size in relation to the rest of the content.

Layouts using clamp

Moving to clamp(), the CSS feels more readable to me now.

padding-inline: clamp(var(--size-2), (100% - var(--max-width)) / 2, 25%);

The size is always 100%, except the padding restricts how wide the content gets. The three arguments are defined in this way for the example above:

  1. At least 16px
  2. Ideally (100% – 1280px)/2
  3. At most 25%

Because this is the padding on each side, the maximum is actually 50% of the overall page width which can be padding. If you get into 8K territory then it can start to stretch but I think for most cases this is fine. I could change the last value to 50% but that doesn't really make sense (50% + 50% = 100%) but it would work.

Interestingly though, as I revisit this bit of CSS I've come to the realisation that my original method was probably more readable using the max() function as it is just two arguments and the at most condition is never met for this use case.

padding-inline: max((100vw - 1280px) / 2, 16px);

I haven't made the change to SkeletonCSS yet, but will be doing so as part of the next commit.

One interesting thing from the docs for clamp, the last two values actually resolve as if using the min() function.

clamp(MIN, VAL, MAX) is resolved as max(MIN, min(VAL, MAX)).

Makes sense but I had looked at the docs to see if the last value was optional. Makes me wonder if I had just overcomplicated my use of min() and max() previously, but at least for now it's readable.


Tags: css, development


Tweet WhatsApp Keep Upvote Digg Tumblr Pin Blogger LinkedIn Skype LiveJournal Like