Scaling sizes (e.g., font size) with the browser width or height
Tags: css, scss, fonts, responsive
Published: 2018-09-09 15:33:53

---
title: Scaling sizes (e.g., font size) with the browser width or height
published: true
description: Linear interpolation between two pixel values allows a size (font, width, margin, etc.) to smoothly scale with the viewport
tags: css, scss, fonts, responsive
---

*My posts are usually notes and reference materials for myself, which I publish here with the hope that others might find them useful.*

---

**DEPRECATED**: CSS in modern browsers provides a built-in mechanism to do this [with the `clamp()` function](https://developer.mozilla.org/en-US/docs/Web/CSS/clamp\(\)).

---

TL;DR: As a SCSS function:

```scss
// y1: smallest size (px)
// x1: smallest browser width (px)
// y2: largest size (px)
// x2: largest browser width (px)
// e.g. 12px @ 375w to 24px @ 1280w = interpolate(12, 375, 24, 1280)
@function interpolate($y1, $x1, $y2, $x2) {
    $m: ($y2 - $y1) / ($x2 - $x1);
    $b: $y1 - $m * $x1; // or $y2 - $m * $x2
    
    @return calc((#{$m}) * 100vw + (#{$b}) * 1px);
}

h1 {
    font-size: interpolate(12, 375, 24, 1280);
    width: interpolate(120, 300, 800, 1280);
}
```

If one of the dimensions of an object should scale linearly with the viewport width (or height), e.g. scaling the font size from 12px at 375w to 24px at 1280w, the interpolated size can be calculated using the slope-intercept line equation (`y = mx + b`) where `y` is the resulting size (in pixels), `x` is set to `100vw` (or `vh`) and `b` is measured in `px`.

This works because `100vw` is exactly 100% of the viewport width, even as the viewport width varies. Thus, when the viewport is 375w, then 100vw equals 375px. Likewise, when the viewport is 1280w, then 100vw equals 1280px. 

So, continuing the font-size example, in the slope-intercept equation, when the viewport width is 375w, the browser sees `100vw` as `375px`, and so the equation is effectively `y = m * 375px + b * 1px`, and likewise at 1280w, `y = m * 1280px + b * 1px`, and for every value in between.

Make your life easier by using [Wolfram Alpha](http://wolframalpha.com/) to compute the equation of the line passing through two points `(x1, y1)` and `(x2, y2)`, where `x1` and `x2` are the size of the viewport dimension (width or height) and `y1` and `y2` are the target sizes at those viewport dimensions.

Continuing the example above, scaling a font from 12px to 24px as the browser width changes from 375w to 1280w, the points are `(375, 12)` and `(1280, 24)`. So we want the equation of the line passing through `(375, 12)` and `(1280, 24)`.

For the line through those two points, [Wolfram Alpha returns the slope-intercept equation](http://www.wolframalpha.com/input/?i=line+through+\(375,+12\)+and+\(1280,+24\)):

```
y = (12/905)x + (1272/181)
```

Written as a CSS rule, this is:

```scss
font-size: calc((12/905) * 100vw + (1272/181) * 1px);
```

Checking the result at the two viewport sizes (375 and 1280):

```
(12/905) * 375 + 1272/181 = 12
(12/905) * 1280 + 1272/181 = 24
```

Above or below those two browser dimensions, if the size should change abruptly, use a media query.