# Fluid Typography

Getting right to the code, here's a working implementation:

``````html {
font-size: 16px;
}
@media screen and (min-width: 320px) {
html {
font-size: calc(16px + 6 * ((100vw - 320px) / 680));
}
}
@media screen and (min-width: 1000px) {
html {
font-size: 22px;
}
}``````

That would scale `font-size` from a minimum of 16px (at a 320px viewport) to a maximum of 22px (at a 1000px viewport). Here's a demo of that, but as a Sass @mixin (which we'll cover later).

See the Pen Base Example of Fluid Type w Sass by Chris Coyier (@chriscoyier) on CodePen.

Sass was used just to make that output a little easier to generate, and the fact that there is a smide of math involved. Let's take a look.

Using viewport units and `calc()`, we can have font-size (and other properties) adjust their size based on the size of the screen. So rather than always being the same size, or jumping from one size to the next at media queries, the size can be fluid.

Here's the math, credit Mike Riethmuller:

``````body {
font-size: calc([minimum size] + ([maximum size] - [minimum size]) * ((100vw - [minimum viewport width]) / ([maximum viewport width] - [minimum viewport width])));
}``````

The reason that math is a little complicated is that we're trying to avoid type ever getting smaller than our minimum or bigger than our maximum, which is very easy to do with viewport units.

For example, if we want the our font size in a range where `14px` is the minimum size at the smallest viewport width of `300px` and where `26px` is the maximum size at the largest viewport width of `1600px`, then our equation looks like this:

``````body {
font-size: calc(14px + (26 - 14) * ((100vw - 300px) / (1600 - 300)));
}``````

See the Pen JEVevK by CSS-Tricks (@css-tricks) on CodePen.

To lock in those minimum and maximum sizes, using this math within media queries helps. Here's some Sass to help out...

### In Sass

You could make a (pretty robust) mixin, like this:

``````@function strip-unit(\$value) {
@return \$value / (\$value * 0 + 1);
}

@mixin fluid-type(\$min-vw, \$max-vw, \$min-font-size, \$max-font-size) {
\$u1: unit(\$min-vw);
\$u2: unit(\$max-vw);
\$u3: unit(\$min-font-size);
\$u4: unit(\$max-font-size);

@if \$u1 == \$u2 and \$u1 == \$u3 and \$u1 == \$u4 {
& {
font-size: \$min-font-size;
@media screen and (min-width: \$min-vw) {
font-size: calc(#{\$min-font-size} + #{strip-unit(\$max-font-size - \$min-font-size)} * ((100vw - #{\$min-vw}) / #{strip-unit(\$max-vw - \$min-vw)}));
}
@media screen and (min-width: \$max-vw) {
font-size: \$max-font-size;
}
}
}
}``````

Which you use like this:

``````\$min_width: 320px;
\$max_width: 1200px;
\$min_font: 16px;
\$max_font: 24px;

html {
@include fluid-type(\$min_width, \$max_width, \$min_font, \$max_font);
}``````

Here's another of Mike's examples, getting fluid rhythm just right:

### Extending the Idea to Headers with Modular Scale

Modular scale, meaning the more space available, the more dramatic the different in size is. Perhaps at the largest viewport with, each header up the hierarchy is 1.4x bigger than the next, but at the smallest, only 1.05x.

See view:

With our Sass mixin, that looks like:

``````\$mod_1: 1.2; // mobile
\$mod_2: 1.5; // desktop

h1 {
font-size: \$mod_1*\$mod_1*\$mod_1*\$mod_1 *1rem;
@include fluid-type(\$min_width, \$max_width, \$mod_1*\$mod_1*\$mod_1 *\$min_font, \$mod_2*\$mod_2*\$mod_2 *\$min_font);
}
h2 {
font-size: \$mod_1*\$mod_1*\$mod_1 *1rem;
@include fluid-type(\$min_width, \$max_width, \$mod_1*\$mod_1*\$mod_1 *\$min_font, \$mod_2*\$mod_2*\$mod_2 *\$min_font);
}
h3 {
font-size: \$mod_1*\$mod_1 *1rem;
@include fluid-type(\$min_width, \$max_width, \$mod_1*\$mod_1 *\$min_font, \$mod_2*\$mod_2 *\$min_font);
}``````

1. Wilbert

Very nice trick! How is the browser support? IE11+?

• Jacob

Should work okay in IE11 and Edge:

• User

Correct me if I am wrong.

I think if you include a polyfill for viewport units and calc you can use this with any browser that the polyfill supports, right? Right?

2. Jacob

I was looking in to integrating this in to my workflow this morning, and you left out a pretty key thing here. This fluid font size calculation should be within a media query with the minimum and maximum viewports set. Otherwise, it’ll continue scaling past the minimum and maximum. See the original post here:

• Chris Coyier

The Sass mixin is the whole kit-and-kaboodle that covers all that, beyond the basic concept.

3. Thomas Kimmich

prove me wrong guys, but the pen above doesn’t work in Safari?

Cheers

Thomas

• Chris Coyier

I think it has to do with live complication of viewport units in Safari. Like if you refresh the page, it’s right, it’s just not fluid as you resize. Bummer. Temporary bug, I would think. Still useful.

• Mike Riethmuller

There’s a bug in some versions of Safari (and IE11) that means it won’t be calculated on resize but as Chris said it should be correct on first load.

This covers the majority of situations. But I hear adding +100% at the end of the calculation will fix the resize bug in Safari.

• Thomas Kimmich

After giving Chris’ shared Sass Mixin a try, it works a treat – even in Safari.

Might it be an issue in CodePen then? I mean all shared pens are struggling in Safari (which is probably the new IE?)

Just wanted to let you know and thanks for sharing this. Very cool.

Cheers

Thomas

• Thomas Kimmich

oops – entirely missed your comment, Mike. Apologize.

Cheers

Thomas

4. dazzle

Can anyone tell me where is the difference to vw?

• Chris Coyier

This technique uses vw. Just not only vw, as then there is no way to control a minimum and a maximum or the other trickery presented here.

• dazzle

I often use vw, but on small devices the text sometimes becomes much too small. Then i correct it by using a media query for the small device and increase the font-size. And with this technique you dont need the media query, right?

5. Mike Riethmuller

Hey Chris, it’s worth sharing these examples by James Nowland: http://codepen.io/jnowland/pen/GWgbMP/ he’s made a really neat mixin and some people may prefer this syntax.

6. Joe Hoeller

I’ve been doing fluid text for the last 2.5y or so.

I use vw’s and rem’s in same CSS property block.

Even use it to treat an entire HTML object as one big design that scales.

• User

Joe, care to hook up and exchange about this, I am also using it to style most of the elements on a page besides the typography to get a neatly flowing & fluid layout going, where can I reach you? Have some (possibly still half baked) pens and gists, perhaps you like to take a look?

7. User

Just today I actually sent an email to Mike outlining a little issue I have with the fluid type Sass mixin, that being, when using it for more than one region/media query, it does produce multiple values for the same selector, see here https://www.sassmeister.com/gist/0a451c254e43c07a7e487771d3590476 (if the CSS is not compiled straight away add a space and remove it again in the SCSS and SassMeister will re-trigger the compilation process)

I have not read it yet, the poly fluid post https://css-tricks.com/poly-fluid-sizing/ , it just hit my inbox and I am going there straight away, perhaps a solution lies there, because I think that is what I am after.

And just like Joe Hoeller writes, not only using this for typography but all styling in the dom, going from extreme 50px width to 2500px and above, great fun and once you get the hang of it you get a truly impressive and responsive layout going.

8. Mike
A simple to use `<a href="https://websemantics.uk/tools/responsive-font-calculator/">fluid-responsive font-size calculator</a>`:
Along with a `<a href="https://codepen.io/2kool2/pen/PKGrdj">Dirty 'orrible 'acky Safari resize fix</a>`.