BAD POSTS DOT BOO

this is just about showing off a clamp function in scss that doesn’t break everything

(it might still break everything) (not my fault though)

Every single clamp function for SCSS requires you either use a division function that’s about to get nuked, or the replacement division function that not only requires an extra @use, but seems to break at so much as a small breeze.

I might be as dumb as a bag of rocks, right, but I also know how SCSS handles calc() in such a way where it still spits out the usual clamp([#]rem, [#]rem + [#]cqi, [#]rem) I’d want, so I threw shit together until the compiler I use stopped yelling at me over it:

@function clmp($min, $max, $width-min: 20rem, $width-max: 40rem) {
    $slope: calc(($max - $min) / ($width-max - $width-min));
    $slopeunit: calc(100cqi * $slope);
    $baserem: calc($max - $width-max * $slope);
    @return clamp($min, $baserem + $slopeunit, $max);
}

Edit the $width-min and $width-max to a rem unit as you need, then call it in a custom property or SCSS variable or whatever like

--cool-text: #{clmp(1rem,1.125rem)};
$cool-text: clmp(1rem,1.125rem);

And it’ll work. Is it the most efficient way to do it? I have no idea, all I know is that setting it up like this is why I can do responsive text that doesn’t implode.

Still gotta work in pixels? Link to footnote 1 Alright, here you go:

@function rpx($px) {
    @return calc(($px / 16px) * 1rem);
}

@function clmp($min, $max, $width-min: 400px, $width-max: 640px) {
    $min: rpx($min);
    $max: rpx($max);
    $width-min: rpx($width-min);
    $width-max: rpx($width-max);
    $slope: calc(($max - $min) / ($width-max - $width-min));
    $slopeunit: calc(100cqi * $slope);
    $baserem: calc($max - $width-max * $slope);
    @return clamp($min, $baserem + $slopeunit, $max);
}

And same as before:

--cool-text: #{clmp(16px,18px)};
$cool-text: clmp(16px,18px);

This also works with the fancy new cqi unit, but considering that conversion is literally just as simple as changing the 100vw in your function to 100cqi, that’s not particularly impressive. To that end, if you’ve got weird containers, you can set custom breakpoints through the last two variables, like so:

$text-footer: clmp(0.7rem, 0.7875rem, 9rem, 16rem);

It’s probably trivial to do this automatically, but the half-conscious version of me who always codes at 1am finds it kind of relaxing to measure it out manually, so hey.


  1. I can’t blame you if you’re old enough to where that would obviously be how you’d think about the web, but to me it just doesn’t work well, knowing what I know. For all the ways rem sounds abstract, it’s pretty undeniably that it’s related to something, even if that something is a generic font size; a pixel, in a world where high DPI monitors exist, usually isn’t even a pixel. By that point, you might as well be using inches as your unit measurement. Return to article via footnote 1


RETURN TO TOP