Sizing type, leading and vertical dimensions with rem-units

  • Categories:

When I started thinking about the redesign of this blog, one of the challenges I wanted to tackle in a smart way was type sizing, especially for smaller screens. Ever since I saw Tim Brown’s talk about modular scales at Build 2010 I’ve been interested in the technique and have used it to inform my designs.

Previous versions of this blog have already been based on a modular scale, yet when it came to smaller screens, it was hard to keep adhering to this scale. What if there was a way to size all the type, leading and vertical dimensions — like top and bottom margins and padding — relatively with one property? I have always been a fan of relative sizing, but have found that em-based values are hard to control over larger codebases. This is where rem-based values come in.

Now I am not going to say this is a silver bullet. Nor am I going to lie and tell you I have seen the light and have changed my mindset in regards to type sizing and vertical dimensions forever. I am going to say that, with a bunch of ingredients, getting this blog to scale down in a responsive manner has been a breeze.

The starting point for this blog post was a flexible design system that was created to respond to different viewports. And with that, I am going to honestly explain how I dipped my toe into these relative sizes, and how this ties in to the use of a modular scale.

1. Learn about rem-sizing

I could probably do a whole article on rem-sizing, but Jonathan Snook did it better already. It boils down to the following:

  1. A rem or root-em is an em value of the root element of the website.
  2. This root element is the html element.

So if the html element’s font size is 16px:

  1. 1rem is 16px
  2. 1.5rem is 24px

2. Implement your design with pixel sizes

Yeah, that’s where it all started. The first implementation of this version of the blog, whilst flexible horizontally, was based fully on pixel dimensions.

There were line-height values that were multiples of a base pixel value, there were type sizes based on a modular scale of 14px and 25px with the perfect fifth as a ratio, and there were vertical margins and paddings.

From this optimal layout implementation, we start refactoring to relative values. Instead of hurting our brain, and losing flexibility at a later date, we should be smart about implementing this.

3. Use a preprocessor to help you out

To preface this, the easy way of calculating and using rem sizes is to set the html element to font-size: 62.5%. This way, if a browser has the default base type size of 16 pixels, it gets calculated to 10 pixels. All rem-based values then become increments of 10. That being said, going to a smaller base size would cause for fewer increments to smaller type sizes and 16 pixels allows for great relative font sizing down.

So let’s get smart. For all sizes that need to be relative, we need to calculate a rem-based value. For this, I use a mixin called "rem", which was slightly modified from Ray Brown’s github repository:

$base_font_size: 16px;

@mixin rem($property, $px_values) {
    $baseline_rem: ($base_font_size / 1rem);
    #{$property}: $px_values;

    @if type-of($px_values) == 'number' {
        #{$property}: $px_values / $baseline_rem;
    } 
    @else {
        $rem_values: ();

        @each $value in $px_values {
            @if $value == 0 {
                $rem_values: append($rem_values, $value);
            } @else {
                $rem_values: append($rem_values, ($value / $baseline_rem) );
            }

        }
        #{$property}: $rem_values;
    }
}

This mixin translates the pixel value you want to give to a property to a rem-based value:

h1 {
    @include rem(font-size, 25px);
    @include rem(margin, 0 0 12px);
}

The above code will translate into:

h1 {
    font-size: 25px;
    font-size: 1.5625rem;
    margin: 0 0 12px;
    margin: 0 0 .75rem;
}

4. Resize with a single font-size property

After you have refactored all of the applicable values to rem-sizes, it only takes one font-size property change to scale all of your type sizes, vertical dimensions etc. In the current version, the 2012 design, of this blog, I use the following media query:

@media screen and (max-width: 600px) {
    html {
        font-size: 87.5%;
    }
}

Et voila, when the browser width goes below 600 pixels, all of the type, vertical margins etc. scale down consistently. And, as with a technique like using CSS sprites to optimise for retina displays, your media queries stay very clean.

5. Practice and Tweak

Again, this is not a silver bullet technique, and just blatantly scaling down all type does not a responsive design make. As always it is about using the right tool for the job.

To me, this technique gives you a good base to start from when scaling down to smaller sizes. A base that should not need all too much tweaking, but is definitely open to it.