Responsive Typography

Mike Riethmuller:

It is possible to have precise control over responsive typography. Using calc() and viewport units you can create fluid type that scales perfectly between specific pixel values, within a specific viewport range.

The formula used is this one:

@media (min-width: #{$min_width}px) and (max-width: #{$max_width}px) {
    font-size: calc(#{$min_font}px + (#{$max_font} - #{$min_font}) * ( (100vw - #{$min_width}px) / ( #{$max_width} - #{$min_width})));
}

As 100vw resembles 100% of the viewport width, the font-size will adjust along with it (between the given min_width and max_width).

Looking for a more simple version, that only enforces a minimum font-size which isn’t limited by a given max_width? This way more simple viewport based typography method has got you covered.

It’s possible to also adjust the line-height, using the same formula. The full code then becomes:

// CONFIG
$min_width: 25;
$max_width: 50;

$min_font: 1;
$min_lineheight: 1.35;
$max_font: 1.2;
$max_lineheight: 1.8;

// DEFAULT (LOWER THAN MIN-WIDTH): USE MIN FONT-SIZE AND MIN LINEHEIGHT
:root {
  font-size: #{$min_font}em;
  line-height: #{$min_lineheight}em;
}

// BETWEEN MIN-WIDTH AND MAX-WIDTH: CALCULATE VALUES USING THE VARIANT 100VW
@media (min-width: #{$min_width}em) and (max-width: #{$max_width}em) {
  :root { 
    font-size: calc(#{$min_font}em + (#{$max_font} - #{$min_font}) * ( (100vw - #{$min_width}em) / ( #{$max_width} - #{$min_width})));
    line-height: calc(#{$min_lineheight}em + (#{$max_lineheight} - #{$min_lineheight}) * ( (100vw - #{$min_width}em) / ( #{$max_width} - #{$min_width})));
  }
}

// GREATER THAN MAX-WIDTH: USE MAX FONT-SIZE AND MAX LINEHEIGHT
@media (min-width: #{$max_width}em) {
  :root { 
    font-size: #{$max_font}em;
    line-height: #{$max_lineheight}em;
  }
}

If you’re looking for the Stylus variant (which is my preferred CSS Preprocessor), here’s one I’ve knocked up:

// CONFIG
$min_width = 10;
$max_width = 100;

$min_font = 1;
$min_lineheight = 1.35;
$max_font = 1.2;
$max_lineheight = 1.8;

// DEFAULT (LOWER THAN MIN-WIDTH) USE MIN FONT-SIZE AND MIN LINEHEIGHT
:root
  font-size unit($min_font, "em")
  line-height unit($min_lineheight, "em")


  // BETWEEN MIN-WIDTH AND MAX-WIDTH CALCULATE VALUES USING THE VARIANT 100VW
  @media (min-width: unit($min_width, "em")) and (max-width: unit($max_width, "em"))
    font-size "calc(%s + (%s - %s) * ((100vw - %s) / (%s - %s)))" % (unit($min_font, "em") $max_font $min_font unit($min_width, "em") $max_width $min_width)
    line-height "calc(%s + (%s - %s) * ((100vw - %s) / (%s - %s)))" % (unit($min_lineheight, "em") $max_lineheight $min_lineheight unit($min_width, "em") $max_width $min_width)

  // GREATER THAN MAX-WIDTH USE MAX FONT-SIZE AND MAX LINEHEIGHT
  @media (min-width: unit($max_width, "em"))
    font-size unit($max_font, "em")
    line-height unit($max_lineheight, "em")

Did this help you out? Like what you see? Consider donating.

☕️ Buy me a Coffee ($3)

It certainly is no obligation but it would put a smile on my face. Thanks! 🙂

Precise control over responsive typography →
Molten Leading in CSS →

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.