RFS: the automated approach for responsive font sizes

rfs.svg

Mastering responsive font sizes for websites has never been easy. Especially for bigger font sizes, multiple breakpoints were needed to gain a little control over the behaviour on all screen sizes. Some improvements were made when calc-functions were introduced to calculate a font size, but still there was no automated way to control all your font sizes for all possible screen widths. That has now changed.

 

RFS to the rescue

RFS is a SCSS-mixin which generates the responsive css for you.

RFS stands for Responsive Font-Size, easy to remember, easy to use. It’s a desktop-first approach which automatically calculates the correct font size for every screen width. Desktop-first approach means you just have got to define your font-size for big screens and the font size will automatically decrease for smaller ones. 

 

The main advantages of using RFS

  • Font sizes will rescale for every screen width, this prevents long words from being chopped off the screen
  • Super easy to use, no need to define complex configurations for each font-size
  • Font sizes of all text elements will always remain in relation with each other
  • Rem-based font sizes will allow the user to change his default font size in his browser. People with limited vision can therefore increase their font size to increase readability.

 

With or without RFS

In the example below, you'll see the difference between a website with and without RFS. The on the left image shows the default bootstrap implementation. In this case smaller words are used (Hello world), but in real life we commonly come across longer words which would be chopped off of the screen. Using RFS, all text elements are scaled correctly, which prevents unwanted behaviour.

Without RFS With RFS
 without-rfs-1.png  with-rfs-1.png

 

 

Video-demo of the problem and RFS's solution

In the first part this video shows the default bootstrap implementation, in the second part RFS takes care of the responsive rescaling of the text.

 

 

How does it work?

RFS splits the calculation of the font-size in 2:

  • 1 static font size for bigger screens
  • 1 adaptive font size which decreases along with the screen width of your browser. This font size is calculated in a media query with css’s calc-function.

There are some configuration variables which can influence the font size's decreasing.

 

To the code

This input (SCSS):

.title {
  @include rfs(60);
}


Will generate this (CSS):

.title {
  font-size: 3.75rem;
}

@media (max-width: 1200px) {
  .title {
    font-size: calc(1.35rem + 3.2vw);
  }
}

Further on, we will explain how these numbers are calculated.

 

Visualisation of RFS

Everything is easier to grasp when you can visualize it. This is what RFS's default configuration looks like:

graph-rfs.png

 

The configuration in detail

There are configuration variables which influence the calculation of the font size. All variables must be set unitless in the configuration:

  • $rfs-minimum-font-size: (in px)
    Font sizes which are calculated by RFS will never be lower than this size.
    However, you can still pass a smaller font size to RFS, but then RFS won't dynamically scale this font size. For example (see graph above): rfs(17) will trigger dynamic rescaling,  with rfs(10) it will just stay 10px all the time.
    Default value: 12
  • $rfs-minimum-font-size-unit: (string)
    The font size will be rendered in this unit. Possible units are px and rem. This setting doesn't influence $rfs-minimum-font-size, which will always be configured in px.
    Default value: rem
  • $rfs-breakpoint: (in px)
    This where dynamic rescaling begins. Above this breakpoint, the font size will be equal to the font size you passed to the mixin.
    Default value: 1200
  • $rfs-breakpoint-unit: (string)
    The width of $rfs-breakpoint will be rendered in this unit. Possible units are pxem and rem. This setting doesn't influence $rfs-breakpoint, which will always be configured in px.
    Default value: px
  • $rfs-factor: (number)
    This is the more complex part. If the font sizes would all resize to the same value when the screen width would be 0, there wouldn’t be a lot of difference between the font sizes on small screens. To prevent this, we brought the $rfs-factor to life.
    Let’s take an example from the graph above: The font size rfs(47) at a screen of 0px is 19px and not 16px because of this factor. This minimum font size is calculated like this:

    Calculate the difference between the font-size (47) and $rfs-minimum-font-size (12)

    47 - 12 = 35
    Divide this number by the $rfs-factor (5)
    35 / 5 = 7
    Add this number to $rfs-minimum-font-size (12)
    7 + 12 = 19

    The higher $rfs-factor, the less difference there is between font sizes on small screens. The lower $rfs-factor, the less influence RFS has, which results in bigger font sizes for small screens. If $rfs-factor is set to 1, there wouldn’t be any difference at all. 1 is the lowest possible value.
    Default value: 5

 

The calculation of RFS

Let’s take back our example of rfs(60). We use the default configuration:

  • $rfs-minimum-font-size: 12
  • $rfs-minimum-font-size-unit: rem
  • $rfs-breakpoint: 1200
  • $rfs-breakpoint-unit: px
  • $rfs-factor: 5

 

SCSS:

.title {
  @include rfs(60);
}

 

The first part of the generated css is pretty straightforward, because $rfs-minimum-font-size-unit is rem, font-size is displayed in rem (60/16=3.75):

.title {
  font-size: 3.75rem;
}

 

Now let’s have a look at the second part. $rfs-breakpoint is 1200px and it is rendered in px because $rfs-breakpoint-unit is px

@media (max-width: 1200px) {
  .title {
    font-size: calc(1.35rem + 3.2vw);
  }
}

We can calculate 1.35rem the same way we did above when explaining $rfs-factor.

Calculate the difference between the passed font-size (60) and $rfs-minimum-font-size (12)
60 - 12 = 48

Divide this number by the $rfs-factor (5)
48 / 5 = 9.6

Add this number to $rfs-minimum-font-size (12)
9.6 + 12 = 21.6

Convert this number to rem
21.6 / 16 = 1.35

 

Now we have a font size of 1.35rem or 21.6px below 1200px. Between a screen width of 0px and 1200px, we use vw-units to increase the font size:

Calculate the difference between the font-size at 0px and 1200px
60 - 21.6 = 38.4

Those 38.4px need to be added over 1200px
38.4 / 1200 = 0.032

The screen width = 100vw, so this number needs to be multiplied by 100
0.032 * 100 = 3.2

Tada! Now you have everything you need to construct the second part.

 

Demotime

We've set up a Codepen demo where you can test RFS and play with the configuration at: http://codepen.io/MartijnCuppens/pen/ZBjdMy. However, if you want to test an entire website, check out the Bootstrap-version: 

 

View the bootstrap-demo with RFS 

 

Let's put it in bootstrap by default!

There is a feature request pending to implement RFS by default in Bootstrap. Put those thumbs up if you would like this feature to be implemented here: https://github.com/twbs/bootstrap/issues/23053

 

Download on github

Download the RFS-mixin here:

https://github.com/MartijnCuppens/rfs

 

Feedback

Let us know if you have any questions or suggestions. Just tweet to @Martijn_Cuppens.