Skip to main content

Using pure CSS the root font size scales up and down proportionately, between defined values, dependent upon the viewport width.

New tool: Responsive font calculator

4th March 2017

A simple utility to easily calculate responsive font values for embedding directly into your CSS.

Easy-peasy, stretch & squeezy.

Current status (25/09/2016): In cross-browser, cross-device testing. Now in full use on this site and in use on components in Tesco's Food Love Stories

In this example the font size is set at 1rem (16px) up to 48rem (768px) viewport width.
It then starts increasing to meet the upper defined value 2em (32px) at 120rem (1920px) wide.
All controlled by a single CSS statement.

Remember to define all font-sizes in em, rem or percent.

Language CSS
/* 1em @ 48em (768px) increasing to 2em @ 120em (1920px) */
@media (min-width: 48rem) {
  :root {
    font-size: calc(100% + ((1vw - .48rem) * 1.389));
    /* .48rem = viewportWidthMinimum /100 */
    /* 1.389rem = 100 * fontSizeDifference / viewportWidthDifference */
  }
}

Where:

Language Mathmatics
fontSizeCalc = 100% + (1vw - 48rem / 100)
fontSizeCalc = fontSizeCalc * 100 * fontSizeDifference / viewportWidthDifference

fontSizeDifference = maxFontSize - minFontSize
                   = 2em - 1em  (or 32px - 16px)
                   = 1em  (or 16px)

viewportWidthDifference = viewportMax - viewportMin
                        = 120em - 48em  (or 1920px - 768px)
                        = 72em  (or 1152px)

Using pixels:
fontSizeCalc = 100% + (1vw - 768px / 100) * 100 * 16px / 1152px
             = 100% + (1vw - 7.68px) * 1.389

Using em or rem:
fontSizeCalc = 100% + (1vw - 48rem / 100) * 100 * 1em / 72em
             = 100% + (1vw - .48rem) * 1.389

Font scaling doesn't stop at the top setting but continues to increment at the same rate.
This behaviour may be stopped, or adjusted further, by adding another media query:

Language CSS
/* Stop font scaling above 1920px */
@media (min-width: 120em) {
  :root {
    font-size: 2rem;
  }
}

Tested on Mac so far: Firefox, Safari, Chrome.
As yet I'm uncertain all browsers convert units in the same manner.

Applied to a Flexbox layout

This method will scale any object which is sized using em or rem.

See the stand-alone demo or the CodePen demo.

Socialise: