CSS

Control vertical rhythm using Sass and Compass

Good vertical rhythm on a website has numerous benefits: aesthetically the design will appear more balanced and polished; for the reader, the content will be more cohesive and easier to read. If you’ve ever read a content heavy website and found it hard for your eyes to jump to the start of the next line, it was probably due to a poor vertical rhythm.

In the old days of print design, vertical rhythm was set using font sizes, line heights, margin and paddings, set in point (pt) size units. Today the same styling is typically controlled using pixel (px) size units. However, responsive design struggles with pixels, as the unit is set once its declared. It’s much better practice to use ems; using ems changing the font size of the parent element will adjust allt he sizes below the element in the DOM.

You can convert from pixels to ems manually, but it requires some maths. Using Sass and Compass this is no longer the case. All the maths is done for you quickly and easily — you can even still declare the sizes in px and they’ll be converted to ems for you.

Using Sass & Compass

If you don’t know what Sass is, where have you been? It’s a CSS pre-processor, the value of which will become apparent. And Compass is an open-source framework built with Sass, it is a collection of helpful tools that make writing stylesheets faster and simpler.

For example, with CSS prefixes you could write a CSS transition like so:

.width-duration-easein {
       -moz-transition-property: width;
       -o-transition-property: width;
       -webkit-transition-property: width;
       transition-property: width;
       -moz-transition-duration: 2s;
       -o-transition-duration: 2s;
       -webkit-transition-duration: 2s;
       transition-duration: 2s;
       -moz-transition-timing-function: ease-in;
       -o-transition-timing-function: ease-in;
       -webkit-transition-timing-function: ease-in;
       transition-timing-function: ease-in;
}
.width-duration-easein:hover {
       width: 80px;
}

To achieve the same code with Sass and Compass, we’d use this code:

.width-duration-easein {
       @include transition-property(width);
       @include transition-duration(2s);
       @include transition-timing-function(ease-in);
}
.width-duration-easein:hover {
       width: 80px;
}

All the hard work of adding the browser prefixes is done for you.

Using Compass’ vertical rhythm

Firstly you need to import Compass’ vertical rhythm module:

@import "compass/typography/vertical_rhythm";

For a vertical rhythm to work there needs to be a baseline font size and line height which all the other sizes are based off. These values should be declared as two variables:

$base-font-size: 16px;
$base-line-height: 24px;

You can set any sizes you like based on the vertical rhythm you want to create but I personally like line heights to be 1.5 times the base font size. In this case 16 x 1.5 is 24.

As these are just the variable declarations nothing in your CSS will have changed. To implement the changes and create the baseline include this mixin (I like to put it just below the variable declarations):

@include establish-baseline;

Once your Sass file has been saved if you view the CSS file you will see the following:

html{
       font-size: 16px;
       line-height: 1.5em;
}

The baseline has now been set and if you notice the line height has been declared in Ems. Compass has done the math based on the variables you set.

Defining headings

Calculating the correct font size and line heights for each heading element could be time consuming. Thankfully Compass can do it for you using the adjust-font-size-to mixin. All you have to do is specify the px size for the element. For each of the heading elements you want to use include the mixin like so:

h1{
       @include adjust-font-size-to(36px);
 }
h2{
       @include adjust-font-size-to(24px);
}
h3{
       @include adjust-font-size-to(20px);
}

Once your Sass file has been saved if you view the CSS file you will see the following:

h1 {
       font-size: 2.25em;
       line-height: 1.33333em; 
 }
h2 {
       font-size: 1.5em;
       line-height: 2em; 
}
h3 {
       font-size: 1.25em;
       line-height: 1.2em; 
}

Compass has done all the math to convert the px sizes to ems and set them accordingly for both font size and line height.

It will often be the case that some white space needs to be added between the headings & paragraphs. Compass has multiple functions and mixins to help with this.

Rhythm function

This function can be used for any margin or padding declarations. In the example below I have used it to set the bottom margin of a heading to add some space between it and the paragraph below. It takes two arguments – the first is the multiple of the base line height you want, and the second is the font size of the element:

h1{
       @include adjust-font-size-to(36px);
       margin-bottom: rhythm(1, 36px);
 }

The rhythm function calculates 1 times the base line height (which is 24px) by the font size (which is 36px). Once the Sass file is saved, if you view the CSS file you will see the h1 styling now looks like this:

h1 {
       font-size: 2.25em;
       line-height: 1.33333em;
       margin-bottom: 0.66667em; 
 }

Compass has calculated the bottom margin value and set it in ems.

Leader mixin

This mixin can be used to add top margin to an element. In the example below I have applied it to all paragraph (p) elements:

p {
       @include leader; 
 }

The mixin is applying 1 base line unit to the top margin. Once the Sass file is saved if you view the CSS file you will see the p styling now looks like this:

p {
       margin-top: 1.5em; 
}

Trailer mixin

This mixin can be used to add bottom margin to an element. In the example below I have applied it to all p elements:

p {
       @include leader; 
       @include trailer; 
 }

The mixin is applying 1 base line unit to the bottom margin. Once the Sass file is saved if you view the CSS file you will see the p styling now looks like this:

p {
       margin-top: 1.5em; 
       margin-bottom: 1.5em;
 }

Finding problems

Sometimes something may not look right, but it does not need to be a daunting task to figure out which element is throwing off the vertical rhythm. Thankfully Compass has a handy mixin to help you identify the problem. The debug-vertical-alignment mixin should be applied to the body element:

body {
       @include debug-vertical-alignment;
 }

Once the Sass file is saved you can view the CSS to see the new styles on the body class but that is not the point of this mixin. If you refresh the browser you will see a baseline grid has been added as the background of the page. This can be really helpful to debug any spacing issues.

Personally I like to include this mixin while in development to make sure each element is spaced correctly on the grid as and when the styles are applied.

You’re now in control

Now you know some of the most useful functions and mixins that are available to you when using Sass and Compass. Applying and controlling your vertical rhythms for responsive layouts should now be a walk in the proverbial park.

Sebastian Green is a front-end developer at Matalan Direct. His passion is using the latest technologies to make the buying experience easy & enjoyable. More articles by Sebastian Green
  • Why litter your code with @includes for prefixes when there is Autoprefixer?

    • sebastiangreen

      The @includes are there for the Compass Mixins – they are not browser prefix CSS declarations.

      • I mean code like @include transition-duration(2s);. Why write that instead of just transition-duration: 2s and let Autoprefixer add the prefixes?

        • sebastiangreen

          Compass does the job of Autoprefixer – check the specs here: http://compass-style.org/examples/compass/css3/transition/

          If you look in the code example at the SCSS then the CSS you can see the output includes the prefixes – no need to throw another plugin at it.

          • And I’ll have to ask again: Why litter your code with @includes for prefixes when there is Autoprefixer?

            Please understand the difference between writing standard CSS which is then enhanced with prefixes (where needed!) via Autoprefixer on the one hand, and writing non-CSS @includes on the other hand.

            Autoprefixer is clearly the superior approach.

          • sebastiangreen

            Please understand that you are including another HTTP request for the extra JS file + also asking the browser to go through and do the processing which will take a few seconds once the page has loaded.

            “Autoprefixer is clearly the superior approach.” – I disagree.

            The CSS file is being served to the browser regardless of any JS files or processing so by having Compass add the prefixes to the standard CSS file you are increasing performance whilst reducing HTTP requests.

          • You misunderstood. Autoprefixer runs during the CSS build process, just like Sass itself. With CSS build processes based on Grunt or Gulp, adding Autoprefixer to the mix is a matter of installing it via npm and inserting one (Gulp) or a few (Grunt) lines of code to the tasks file, e.g.

          • sebastiangreen

            Ah right, sorry I assumed (wrongly) that you were including autoprefixer.js in your pages.

            If the process is happening at build time, effectively the same thing is happening – the CSS file output has the necessary prefixes.

            I get what you are saying by the Sass file will have some @include statements in it, but I personally like that – if I need to compare the CSS to the Sass file it is more obvious what is happening. Granted if I know the build process is running Autoprefixer I should be able to deduce that it is adding them at build time, but it is not as obvious if I do not know the build process.

            Also, not everyone uses Grunt or a similar build process – what if someone is just using Codekit to interpret their Sass.

            As with most things in programming, there is never 1 perfect solution. It is impossible to say “this solution is better than that solution” in every situation. I typically find that when developers have that attitude, they are limiting their options.

  • Theodoros Ploumis

    I prefer using https://github.com/csswizardry/typecsset for vertical rhythm since I try to move from Compass to LibSass

    • sebastiangreen

      This does look interesting – simial concept to what Compass does by having base font and line height values set then all the calculations are carried out via mixins. Personally I don’t like to include too many separate items in my includes list – it can get a bit hard to control. I like that in Compass you can just include the parts you want without having the whole library.

Home CSS Deals HTML HTML5 Java JavaScript jQuery Miscellaneous Mobile MySQL News PHP Resources Security Snippet Tools Tutorial Web Development Web Services WordPress