Last Updated: February 25, 2016
· kennybrijs

Responsive typography made easy

Edit July 20th 2015: If you want your typography to scale differently (e.g.: Your headings and your paragraphs don't need to just scale up by 20% on a different resolution, you want them both to have a different size), there’s a great article on Smashing Magazine about that: Responsive Typography with Sass Maps

Font sizes should differ on different devices (smartphone/tablet/desktop) because people read from these devices at different distances: you hold your phone closer to your face than your desktop screen. For more information on this, check responsive typography, the basics.

But what’s the most practical approach to do this? (according to me)

  • Use rem’s (and a Sass mixin for a px fallback)
  • Switch the html’s default font-size at different resolutions (since we're using rem’s all font sizes will decrease/increase with it)

Note: We’re using rem’s because em’s can be tricky:

One of the problems with using "em" as font sizes is that they cascade, so you are forever writing rules that select nested elements to reset them back to 1em; CSS3 now has rem ("root em") to prevent that issue. Just declare a px fallback and you can use it today. Snook shows us they way.

Learn more about rem’s at

Defining font-sizes with rem's

I put my font sizes in variables to ensure consistency through the whole website:

$font-size-xs: 11px;
$font-size-s: 14px;
$font-size-m: 16px;
$font-size-l: 18px;
$font-size-xl: 24px;
$font-size-xxl: 36px;

This mixin converts the pixel font size to a rem format, with a px fallback

@mixin font-size($px, $base: 16px) { // 16px is the browser default
   font-size: $px; // px fallback
   font-size: ($px / $base) * 1rem; // calculate rem font-size

Mixin usage:

    @include font-size($font-size-xl);

Mixin output:

    font-size: 24px; // overwritten by rem declaration below, IF rem's are supported
    font-size: 1.5rem;

Resizing font sizes at different resolutions (mobile first):

html{ // Smallest resolutions
    font-size: .8rem;

@media only screen and (min-width: 480px) { // 480px and up
        font-size: .9rem;

@media only screen and (min-width: 768px) {
        font-size: 1rem;

That’s all Folks!

Yup, that’s how easy it is, desktop screens will now have the sizes defined in your variables. Smaller screens will have smaller font sizes, creating a better reading experience. Try to reach a line lenght of ~50–60 characters for body copy on each device.

6 Responses
Add your response

I'm going to try this on my next project, thanks Kenny!

over 1 year ago ·

Glad to hear that mattquirk, good luck ;)

over 1 year ago ·

And on the px fallbacks? Surely they'll get the same font-size regardless of the font-size on the html.

Maybe you should pass a different $base instead of changing the font-size on the html.

over 1 year ago ·

Yes, browsers not supporting rem's wont get responsive type, but that's not a bad thing per se because most mobile browsers support it and old desktop browsers will just get te "regular size" with pixels, which they would also get if they supported rem's

The thing with changing the $base—if you mean the base font-size—is that you can't change that with media queries. The $base variable is set in SASS (or LESS) which is then compiled to CSS. The media query logic is executed in the browser (the CSS) and there you can't change the SASS/LESS variables when the media query detects a certain screen size.

Is this an answer to your question or have I misunderstood something?

Grtz ;)

over 1 year ago ·

Tried the code examples. Too bad it didn't work. Regardles of the browser window size, the fixed pixels values were always used. Tested with Safari 7.0.5. - Either I did something wrong (probably) or this article needs clarification :-)

over 1 year ago ·

Hi moonbeetle ;)

Can't see your code, but check out this article:

Once you get it working like that you should be able to figure out the rest, the code in this article is just an automation of the principle explained there ;)

Hope it helps

over 1 year ago ·