# Can type scale fluidly with screen size?

**What is fluid type?**

Type design on the web can be separated into two categories: **static** and **responsive**.

** Static** type ignores the dimensions of its screen; its characteristics are independent of it.

** Responsive** type responds to the dimensions of its screen and adjusts its characteristics based off of them.

Responsive type can be further categorized into **adaptive** and **fluid**.

** Adaptive** type only adjusts its characteristics at certain screen dimensions, called *breakpoints*.

** Fluid** type adjusts its characteristics in proportion to screen dimensions constantly.

Adjust your window’s width to see how each of these three categories of type behave under changing screen width (all three are identical at screen widths > **1600px**):

[codepen:/mikevonwang/pen/OjbPgE]

## Why would someone use fluid type?

**Fluid** type will always stay at a constant cpl, and therefore at a constant *aspect ratio*. Any layout which requires a block of text to stay at the same aspect ratio (text boxes next to images, for example) without scrolling, wrapping, or truncating would require the use of fluid type.

Plus, using fluid type in a website always gets some rad street cred.

## Why would someone not use fluid type?

The central goal for typesetters is *readability*. To that end, **font size** and **characters per line (cpl)** contribute the greatest. As a general rule, body text should be twixt **50-75** characters per line, and **14-16**px tall.

**Static** text quickly drops below optimal cpl as screen width decreases, but its constant font size means that the text is always legible. **Adaptive** and **fluid** text, by contrast, stay close to optimal cpl at most screen sizes, but their decreasing font size also means that the text quickly becomes unreadable and then illegible.

This is the key drawback of fluid type. For type set at a large size (titles, headers), this issue is not significant. For body text that is already at a small font size, this issue quickly prevents fluid type from being the most effective choice.

## How does someone create fluid type?

The key to fluid type is *linear interpolation*. If we know two input/output pairs (**x0**, **y0**) and (**x1**, **y1**), and a desired input value **x**, we can draw a line twixt the two pairs, and calculate the output value **y** corresponding to **x** from that line. The formula for this calculation is:

`y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0));`

For example, if we know that at a screen width of **1000px**, a block of text should have a font size of **24px**, and at **500px**, it should have a font size of **16px**, we can use the following CSS rule to describe this behavior:

```
.fluid-type {
font-size: calc(0% + 16px + (100vw - 500px) * ((24 - 16) / (1000 - 500)));
}
```

Note the presence of `0%`

at the beginning of the `calc()`

function. This is necessary, because Safari will not allow viewport units inside `calc()`

functions unless at least one operand has units of percent.

Also note the absence of units from the last four numeric values in the `calc()`

function. This is necessary, because `calc()`

does not allow multiplication or division by non-scalar values. The 2nd numeric value can have any length unit, but `px`

should be used for consistency.

This CSS rule applies to *all* screen widths, not just to screen widths twixt **500px** and **1000px**. In fact, *any* two input/output pairs that lie on the line between (**500px**, **16px**) and (**1000px**, **24px**) could be selected, and the rule would function identically. For example, if we changed **500px** to **750px** and **16px** to **20px**, the new rule would be indistinguishable from the previous:

```
.fluid-type {
font-size: calc(0% + 20px + (100vw - 750px) * ((24 - 20) / (1000 - 750)));
}
```

In order to restrict the rule to certain minimum/maximum font sizes, one would have to use media queries. For example, to restrict the text from the previous example to a minimum font size of **16px** and a maximum of **24px**, we can use the following CSS rules:

```
.fluid-type {
font-size: 24px;
}
@media (max-width: 1000px) {
.fluid-type {
font-size: calc(0% + 16px + (100vw - 500px) * ((24 - 16) / (1000 - 500)));
}
}
@media (max-width: 500px) {
.fluid-type {
font-size: 16px;
}
}
```

If we use SCSS, we can write functions to do linear interpolation for us, so we don’t have to write out the formulae for every single piece of fluid type we want to implement.

```
@function st($n) {
@if type-of($n) == 'number' and not unitless($n) {
@return $n / ($n * 0 + 1);
}
@else {
@return $n;
}
}
@function li($x0, $x1, $y0, $y1, $x) {
@return calc(0% + #{$y0} + (#{unquote($x)} - #{$x0}) * (#{st($y1 - $y0)} / #{st($x1 - $x0)}));
}
```

`st()`

strips an input of its unit, i.e. turns it into a scalar.

`li()`

performs linear interpolation. Note that the first four inputs must all have the same units, preferably `px`

.

Note the presence of the `unquote()`

function within `li()`

. This is necessary if we wish to use a `calc()`

function for the value of `$x`

, because Safari does not allow nested `calc()`

functions. Values for `$x`

that are not `calc()`

functions can be passed in as is, but values that are need to be passed in as a string, i.e. `'(((100vw - 80px) / 3) - 60px)'`

.

Now, we can simply call `li()`

to implement fluid type:

```
.fluid-type {
font-size: 24px;
}
@media (max-width: 1000px) {
.fluid-type {
font-size: li(500px, 1000px, 16px, 24px, 100vw);
}
}
@media (max-width: 500px) {
.fluid-type {
font-size: 16px;
}
}
```