CSS math function clamp()

Hi, I’ve got a situation where I need some heading text to scale it’s font-size from 540px to 750px viewport widths.

The CSS clamp() function does just what I need. However I’m concerned about browser support for it as it looks like it just gained support for current ios safari and android (chrome and FF) within the past few months.

It seems a little to risky to use it right away.

I am able to do what I need with min/max media queries at the expense of a couple of extra lines of CSS. I’ll be using two media queries anyways for other elements on the page.

Am I correct in thinking that I should hold off on using clamp() for now?

Here’s a test case using clamp and min/max queries that produce the same results.

<!doctype HTML>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Fluid Heading Text</title>
<style>
body {margin:0;text-align:center}

header, .fluid {
  width:100%;
  max-width:900px;
  margin:2em auto;
  border:1px solid;
  box-sizing: border-box;
}
/* default font size */
.clamp h1, .fluid h1 {
  font-size: 36px;
}

@media all and (max-width: 750px) {
  header, .fluid {background: orange;}
  .clamp h1 {
    font-size: clamp(24px, 4.8vw, 36px);
  }
}

/* Fluid font-size  */
@media all and (min-width: 541px) and (max-width: 750px) {
  .fluid h1 {
    font-size: 4.8vw;
  }
}
/* Define min font size */
@media all and (max-width: 540px) {
  header, .fluid {background: yellow;}
  .fluid h1 {
    font-size: 24px;
  }
}

</style>

</head>
<body>
<h1>Fluid heading text from 540px to 750px viewport widths</h1>

<header class="clamp">
  <h1>This fluid text is 4.8vw with font-size: clamp</h1>
</header>

<div class="fluid">
  <h1>This text is 4.8vw with min/max media queries</h1>
</div>

</body>
</html>
1 Like

The method I use for dynamic text size is to combine em with vw units via the better supported calc(), eg:-

h1 {
   font-size: calc(1em + 3vw);
}

It does not have min/max thresholds, but the em value stops it going too small, as it likely would with vw units alone, so that tkaes care if the min size.
If max size is a problem, you will need a query to put the stops on it.
But with a bit of tweaking to get the right balnace between the fixed and dynaminc size, it can be quite effective for big, bold headings that need to re-size for small screens.

Though clamp is a new one for me. Worth looking at for this kind of thing.

1 Like

Hi Sam, Yes that is what I’m doing with it. It’s a google cursive font called ‘Yellowtail’ that is used in my header. I’m setting it in pixels because it has to position around some background images. I can’t use ems/rems since I have no way of knowing what the users default font size is.

I had tried using a version of font-size: calc(1em + 3vw); earlier but couldn’t get the smooth scaling that font-size: __vw; alone gives me.

That’s what the clamp() function does. It keeps the smooth scaling between min/max by using vw on it’s own.

In my example code, if you look at the computed font-size of each test case side by side you will see that they are identical as you size the viewport between 540 and 750. The clamp function just eliminates the need for an extra query to set the min font size.

It has good support (apart from IE) and I would start using it now. You can always use it in @supports media query if you want to provide a fallback.

There’s an interesting article on CSS tricks you may like.

2 Likes

Great, that’s what I wanted to hear! :slightly_smiling_face:

I’m not worried about IE anymore, and I’m glad to see Edge using the Blink engine now too. That should be the end of an era for IE bugs.

Thanks, very informative article. It looks like clamp is going to be a game changer now.

1 Like

Hey, one more thing Paul. In the past I’ve asked you about making the company name the <h1> tag in the header (and for the page). I only use one h1 tag per page. If I remember correctly we both concluded that to be the best route for a business site.

In the past I was doing this…

    <div class="heading">
      <h1>Hopson Custom Woodworks <span>Custom Cabinets &amp; Millwork</span></h1>
      <p class="since">High Quality Cabinetry Since 1984...</p>
    </div>

After going through the google guidelines on the recent image replacement thread. It got me concerned about the span tag nested in my h1. Then span is set to display block and drops to the next line with smaller text.

With the html structure above though it reads out as one string of text to a search engine. It’s using the word “custom” twice. I’m afraid they might interpret that as keyword stuffing.

I am now going to change the span to an h2 tag, with another h2 tag lower down specific to each pages title.

    <div class="heading">
      <h1>Hopson Custom Woodworks</h1>
      <h2>Custom Cabinets &amp; Millwork</h2>
      <p class="since">High Quality Cabinetry Since 1984...</p>
    </div>
    <div class="inner">
      <h2>Page Specific Heading</h2>
    </div>

I think that creates a much better page outline and removes the risk of keyword stuffing.

1.) Business Name
2.) What They Do
2.) Page Specific Heading

Thoughts?

To be honest I prefer the original version as I don’t think you would be penalised for using the word custom ‘twice’ (unless you said Hopson Custom twice in the same sentence).

However I think the h1,h2 version will be ok as well and is much like talked about here..

I generally try not to out-think search engines but rather decide what is more useful to my viewers to know.:slight_smile:

Sometimes you can sweat the small details too much and lose the bigger picture :wink:

(If you had the facilities you could try either version for a month or so and monitor which gets the most traction.)

2 Likes

I’m also imagining someone using a screen reader. To me it would sound redundant read out as one string of text, … custom … custom …

I think that’s what I’m going to do. It will still give the same visual effect for unimpaired users while removing the redundancy and any doubts about keyword stuffing.

Thanks for the insight!

1 Like