Heads up! This blog post hasn't been updated in over 2 years. CodePen is an ever changing place, so if this post references features, you're probably better off checking the docs. Get in touch with support if you have further questions.

It makes good sense that font-size changes depending on the screen. 24px type might look great on a very big screen, but be impractical on a 360px wide screen when even at 100% width you can only fit 3-5 words per line. Adjusting down to something like 16px might retain the same feel and still be nicely readable.

A common way to do that is to pick some breakpoints and adjust the font-size accordingly. Perhaps at the :root, like:

html {
  font-size: 16px;
}
@media (min-width: 350px) {
  html {
    font-size: 18px;
  }
}
@media (min-width: 800px) {
  html {
    font-size: 22px;
  }
}
@media (min-width: 1200px) {
  html {
    font-size: 24px;
  }
}

If all the other font-sizes used throughout the site are relative (like %, rem, or em), these adjustments might work great. Perhaps you get even more fine-grained than that and also adjust things in smaller containers.

But this is all a bit like adaptive layout, isn’t it?

The kind of layout where at certain breakpoints things kinda snap into place? And at the sizes that don’t match those exactly, there are essentially “black bars” that fill the space.

It became more popular to “go fully responsive” with layouts, where widths were largely in percentages, so that you get to use as much room is available at any given screen size. To a point, anyway.

You can also “go fully responsive” with typography, in a sense. There are a number of Pens by Mike Riethmuller that tackle things like fluid type size, fluid modular scale, and even fluid vertical rhythm.

Pretty impressive to watch type resize that that and never reflow!

I loved the idea so much I stole the idea for the type on blog posts here on CodePen.

It’s worth reading up on Mike’s technique here, but a distilled Sass version is like:

@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;
      }
    }
  }
}

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

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

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

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);
}