How To Use Compass Vertical Rhythms

Vertical Rhythms are part and parcel of good web design. Although they are important, they can be an incredibly chore to calculate.

Luckily, Compass has a great vertical rhythm module that helps clears this mess up.

Compass Vertical Rhythm

Compass requires the use of Sass, a css preprocessor. If you’re not sure whether you want to start using a preprocessor like Sass, check out one of my previously written articles.

The Compass Vertical Rhythm reference is great, but may possibly overwhelm if you’re new to it.

In this post, we’re going to talk about how to use this powerful addon.

Note: You need to have the alpha version of Compass installed to before this tutorial will work. You can install compass alpha with

$ sudo gem install compass --pre

Configuring Vertical Rhythms

The first step to using Compass vertical rhythms is to configure a few variables. You can ignore most of the variables listed on the compass reference page with the exception of these two.

// Compass Vertical Rhythm Settings
$base-font-size: 20px; // Sets the base font size
$base-line-height: 36px; // Sets the base line height 

The following two modules are useful, but completely optional

$round-to-nearest-half-line: true; // Allows compass to round to  multiples of 0.5x line height 
$rhythm-unit: "rem"; // Sets rhythm unit to rem. Remove to use default em unit. 

I personally like to allow compass to automatically round to the nearest half line instead, and this can be very helpful when large header titles have to get bumped to two lines.

Rem unit is one of my favourites, and I use them for my development. However, it is not supported by IE 8. Unless you’re willing to get a polyfill for the rem unit, you might want to stick with default ems.

Now that you’ve set the basic compass variables, you’re more to less good to go. I will go one step further and list down basic font sizes that will be used in the website.

// Note these are custom. You have to tell compass to use them yourself 
$h1-fz: 45px;
$h2-fz: 30px;
$h3-fz: 24px;
$h4-fz: 20px;
$h5-fz: 16px;
$h6-fz: 13px;

Using Compass Vertical Rhythm

Telling Compass to set the baseline is quite simple, with the use of only one line of code.

// Establishes baseline with Compass.
@include establish-baseline;

This sets the default font size and line height you have previously declared into the html selector. The output will be slightly different depending on whether you’re using the experimental version of compass.

/* Standard Compass Version. At the time of writing this is v0.12.2.  
Thanks to Maximilien for noticing this */ 
* html {
  font-size: 125%; }

html {
  font-size: 20px;
  line-height: 1.8em; 
}

/* Experimental Compass Version. At the time of writing this is v1.0.0.alpha.18 */ 
html {
  font-size: 125%;
  line-height: 1.8em;
}

Remember the various heading font sizes we set earlier? You have to tell compass to use them with the adjustfont-size-to mixin. This mixin takes up to 3 arguments.

// Adjust font size to mixin. 
// Note that those in [] are optional arguments. 
adjust-font-size-to($to-size, [$lines], [$from-size])

$lines = number of line heights this font is suppose to take up. 
$from-size = current font size used to adjust to target font size. 

$lines will default to the nearest line height multiple that can accomodate the target font size. It will round to the nearest half line height if $round-to-nearest-half-line is set to true. This number need not be an integer.

For example, if the target font size is 45px, the base-line-height is 36px, the resultant line height will either be 54px or 72px (in em or rem unit), depending on what $round-to-nearest-half-lineis set to. By stating $lines explicitly, you are telling compass to use your declaration instead of calculating them.

If you’re using ems as the rhythm unit, you have to tell compass to use the $from-size variable if the current container has a different font size than the base declared up above.

If you are using rems, you don’t have to bother about $from-size at all.

Here’s how you can use the adjust-font-size-to mixin. You can use this anywhere you need to.

h1 {
  @include adjust-font-size-to($h1-fz);
}

h2 {
  @include adjust-font-size-to($h2-fz);
}

h3 {
  @include adjust-font-size-to($h3-fz);
}

h4 {
  @include adjust-font-size-to($h4-fz);
}

h5 {
  @include adjust-font-size-to($h5-fz);
}

h6 {
  @include adjust-font-size-to($h6-fz);
}

The rhythm() function

The rhythm() function is the single most useful function in Compass. It allows you to quickly calculate multiple line-heights worth of margins and paddings without doing the math. This number need not be an integer

.example-selector {
  margin: rhythm(1) 0; // This translates to 36px margin top and bottom since the declared base lineheight is 36px. 
  padding: rhythm(1) 0; Similarly, this adds 36px of padding instead
}

In Conclusion

That’s really all to it to using Compass for vertical rhythm. Its incredibly quick and easy. There are many other functions provided that I don’t use often, but you can find them all in the reference.

Try using vertical rhythms in your next project and let me know how you find it!

Resources

http://24ways.org/2006/compose-to-a-vertical-rhythm/ http://typecast.com/blog/4-simple-steps-to-vertical-rhythm http://drewish.com/tools/vertical-rhythm/

Want more of this?

Get similar articles as soon as they are published

  • Minh Phạm

    Why “rem”? What is the benefit of using “rem”?

    • http://www.zell-weekeat.com/ Zell Liew

      Rem stands for Root em, and its easier to calculate compared to em since the base size used for calculations is always with reference from the root defined in html {} with @incude establish-mixin.

      Em always calculates with its base as the parent container, so if there are any changes to the parent container size, the calculation has to change to make sure you get the correct size.

      Take a look at this post http://snook.ca/archives/html_and_css/font-size-with-rem. It explains rems very clearly.

  • Max

    Why is it that when I do : @include establish-baseline;

    it outputs :

    * html {
    font-size: 87.5%; }

    html {
    font-size: 14px;
    line-height: 1.71429em; }

    Instead of:

    html {
    font-size: 87.5%;
    line-height: 1.71429em; }

    ?

    • http://www.zell-weekeat.com/ Zell Liew

      That is interesting, I’m wondering if its because I’m using the compass experimental version. I wasn’t able to reproduce that on my computer.

      When I did a double check with the compass reference, @include establish-baselinse outputs the code as you pasted because IE 6 had some problems rendering fonts set in percentages.

      I have a feeling It might switch to the one I posted if you set legacy support for ie 6 to be false, like so
      $legacy-support-for-ie6: false;

      However, this is not tested yet so I’m not sure. Let me know if this works for you?

  • Minh Phạm

    When i add margin with function rhythm(), It seems give us “rem” unit. Can we make it fallback with px unit? Or we should use “Polifiil” ??

    • http://www.zell-weekeat.com/ Zell Liew

      It gives rem unit if you have set the rhythm unit to rem as mentioned above. If you leave that out however, you’ll get the em unit instead.

      I usually use polyfills for rem when I work with IE8. If you’re not comfortable with polyfills, then use the default em unit instead.

  • http://bouteillenicolas.com Nicolas Bouteille

    Looks like $rhythm-unit: “rem”; does not work yet on Compass 0.12.2 but $font-unit: 1rem; does work. http://compass-style.org/reference/compass/typography/vertical_rhythm/

    Did you make a mistake here or did I miss something?

    Looks like $rhythm-unit: “rem”; is something coming in the next versions and that they will provide pixel fallback for IE8- no ?

    http://stackoverflow.com/questions/18434054/how-to-make-compass-vertical-rhythm-output-rems-instead-of-ems-with-px-fallback

    EDIT :

    I just tried to set $font-unit: 1rem; to use REMs on compass 0.12 but now the line-height set by adjust-font-size-to is in REM too so it is relative to the base font size.
    So I have my h1 3.375rem (54px) but line-height 1.3333rem of 16px so not big enough at all… Is it just Compass 0.12 simply not ready to use rems or me who does not do things properly ?

    EDIT : looks like $relative-font-sizing needs to be set to false to use REMs. I would have thought REMs would be considered relative too…

    • http://www.zell-weekeat.com/ Zell Liew

      You’re right here. I missed out that you need to have the alpha version of Codekit installed to use the rem unit with vertical rhythms. You can install it with the –pre suffix and the article should work fine.

      Thanks for spotting!

  • Gonzalo2683

    How to use vertical rhythm and images?

    • http://www.zell-weekeat.com/ Zell Liew

      Unfortunately, the vertical rhythms in compass only applies to text. What I usually do for images is that I ensure a margin of rhythm(1) below the image.

      Sometimes when its applicable, I regulate the height of the image with the height property as well.

      When its responsive and height of the image needs to change at every viewport, it gets a lot harder