Aesthetic Sass 3: Typography and Vertical Rhythm

In both print design and web design, typography plays an important role. After all, content is king, and text content is prevalent in the web. That is why it is important to adopt a content-first approach to design. When content is well-designed, everything else (layout, structure, colors, transitions, etc.) will follow.

There are many useful tools and utilities in Sass for customizing typographical styles. Instead of trying to recreate these tools, we will exploring:

  1. How to organize typographical styles in Sass, and…
  2. The use of vertical rhythm for layout.

We will be recreating this mockup below (by talented designer Thomas Budiman) to demonstrate how using both a modular type scale and a vertical rhythm can provide a systematic way of laying out content in your projects, without having to use magic numbers.

aesthetic-sass-typography-preview

Modular Type Scales

Choosing a modular type scale answers the question, “Which font sizes should I use in this project/design?” It provides you a set of proportional values to set the varying sizes of text used throughout a consistent design. From the Elements of Typographic Style:

A modular scale, like a musical scale, is a prearranged set of harmonious proportions. – Robert Bringhurst

There are many tools that can be used to choose a modular scale, some of which can even be easily used with Sass:

Choosing a modular scale is up to you and/or your designer(s). Sometimes, the chosen scale will be slightly changed to use discretionary values (or rounded values), and that’s okay. The point is to choose a type scale and stick with it throughout the project.

For the example, I’ve chosen a scale based on 1rem with a ratio of 1.333 (4:3, or a perfect fourth). Each value of the scale can be represented in a Sass map:


$type-scale: (
  -1: 0.75rem,  // small text
  0: 1rem,      // body text
  1: 1.333rem,  // large text
  2: 1.777rem   // main heading
);

The map keys represent the power of the ratio; e.g. 1rem * 1.3332 = 1.777rem. You can also have the map keys represent the semantic meaning of each value, such as small: 0.75rem.

Let’s use these values (with a small helper function) to start the typographical styles of this design:


@function type-scale($level) {
  @return map-get($type-scale, $level);
}

Baseline Grids and Vertical Rhythm

When you saw the above design, did you ask yourself, “How am I supposed to know exactly where all the items go vertically?” Turns out, designers frequently use what’s called a baseline grid to properly layout elements and to provide consistency in design. It is a repeating set of vertical guides where the baseline of text can be aligned to, but it’s not limited to just typography. Baseline grids are very useful for aligning other visual elements, such as buttons, and even for overall content layout.

The distance between baselines is known as line height or leading. Because we want the line height to be consistent regardless of font size, we’ll be using unit values to ensure this*. One way to determine each font size’s respective line height is:

  1. Determine the base line height, which is a ratio (usually between 1.2 and 1.5) multiplied by the base font size. E.g. 1.25 * 1rem = 1.25rem.
  2. Use a multiple of the base line height for each font size, typically closest to (but larger than) the font size. E.g. for 1.777rem, a line-height of 1.25rem * 2 = 2.5rem is appropriate.

$base-font-size: 1rem;
$base-line-height: $base-font-size * 1.25;

$line-heights: (
  -1: $base-line-height,
  0: $base-line-height,
  1: $base-line-height * 2,
  2: $base-line-height * 2
);

// Again, we can make a helper function:
@function line-height($level) {
  @return map-get($line-height, $level);
}
  • Common wisdom in CSS is to use a unitless number for the value of line-height to avoid unwanted line-height cascading for nested elements containing text. However, in this system, all elements containing text should/will have an explicit line height set, so they won’t be influenced by the cascade.

Using Vertical Rhythm for Layout

Of course, not all of the content in a design will be text. The calculated line height can be used in layout for determining vertical padding or margins, so that other elements are also aligned to the baseline grid. For example:


.heading-1 {
  margin-bottom: $base-line-height;
}

.recipe-button {
  // ... other styles
  height: $base-line-height * 2;
}

Relative Vertical Rhythm (or Breaking the Rules)

The above system for using line height and aligning content to a consistent baseline grid are simply guidelines, not rules. With this said, sometimes a design might deviate from a baseline grid, especially if it’s not text-heavy or if tighter vertical spacing is desired.

When this is the case, vertical rhythm can still be assumed with relative vertical spacing, as long as a consistent value (or proportional pair of values) is used, such as 1rem or 0.5rem, 1rem. This can make it easier to rapidly scaffold and code a design.


// Example using 1rem or 0.5rem consistently,
// regardless of base line height
.field, .heading-1, .paragraph /* etc. */ {
  margin-bottom: 1rem;
}

.field > .label {
  display: block;
  margin-bottom: 0.5rem;
}

Putting It All Together

Using the original mockup, let’s put this to code and see how aligning to a vertical baseline grid produces an aesthetic design on the web, without using magic numbers. We’ll use a @mixin to help us out:


@mixin type-setting($level: 0) {
  font-size: type-scale($level);
  line-height: line-height($level);
}

// The main heading
.heading-1 { @include type-setting(2); }

// The smaller top heading
.heading-2 { @include type-setting(-1); }

.paragraph { @include type-setting(0); }

.recipe-value { @include type-setting(1); }

.recipe-text { @include type-setting(-1); }

.recipe-button { @include type-setting(-1); }

With the rest of the styling added, here is our end-result (hover over the recipe card to see the baseline grid):

See the Pen Baseline Grid Demonstration by David Khourshid (@davidkpiano) on CodePen.

Investing a little bit of time into using a baseline grid and calculating font sizes based on a modular scale allows you to create aesthetic, consistent styles without the need for magic numbers or pixel-pushing. Vertical rhythm can also be used for more than just text elements — it can be used to calculate vertical margins and/or padding between elements, as well as adjusting the height of static elements so that they align to the baseline grid.

As always, the guidelines above are merely suggestions. There’s more than one way to organize your type settings (see the SCSS in the Codepen example) and you might define your Sass functions and mixins differently, but the underlying principles are the same: organize important style values into maps, lists, and/or variables and stay consistent with these values. That way, they become easier to use and manipulate throughout your Sass projects.

David Khourshid

David Khourshid is a front-end web developer in Orlando, Florida. He is passionate about JavaScript, Sass, and cutting-edge front-end technologies. He is also a pianist and enjoys mathematics, and is constantly finding new ways to apply both math and music theory to web development.