Modular typography

Creating a modular typography system in CSS creates an extremely reusable font-size system with a harmonious vertical rhythm.

Steps to creating a type system

  1. Choose the typeface for the body copy.
  2. Choose an appropriate font-size the body copy—usually 16px (100%).
  3. Choose an appropriate line-height for the body text—usually between 1.3–1.5 (depending on screen size).
  4. Choose a type scale, often based on a musical or other natural scale.
  5. Set up the CSS font-sizes, line-heights, and margins to create the rhythm.
  6. Create a set of utility classes to be used throughout your design.

Example type choices

  • font-family: Georgia
  • font-size: 16px (100%)
  • line-height: 24px (1.5)
  • type-scale: 1.125 (major second)

How to choose a type scale


CSS for modular typography

I usually start my type-scale with the h6 set at the same font-size as the body copy, 1rem, then work upwards from there.

To calculate the font-size there’s just some simple multiplication:

font-size: previous-font-size × type-scale

So for the h5, it would be 1 × 1.125.

h5 {
  font-size: 1.125rem; /* (1 × 1.125) */

h6 {
  font-size: 1rem;

A more general equation would be this:

font-size: base-font-size × type-scale ^ distance-from-base

Using the formula to calculate the h1:

h1 {
  /* (1 × 1.125 ^ 5) - H1 is 5 steps away from the base font-size */
  font-size: 1.8020rem;

Re-usable classes

With a font-size system set to a scale we will want to use those font-sizes outside of h1 so we should assign classes to them.

Some designers like to use the Greek alphabet for their font-sizes, some like to use the Metric prefixes. I personally prefer the Metric prefixes because they make sense to me and I don’t know whether alpha is my biggest or smallest font-size.

So, we would then assign classes to all the significant font-sizes:

.exa {
  font-size: 1.8020rem;


.kilo {
  font-size: 1rem;

Often we need larger font-sizes (for banners or hero graphics) and smaller font-sizes (for captions or footnotes). So we should make classes that go above and below the heading sizes:

.yotta {
  font-size: 2.2807rem;

.zetta {
  font-size: 2.0273rem;


small, .milli {
  font-size: 0.8889rem;

.micro {
  font-size: 0.7901rem;

Overall I want to have 10 type sizes: 7 bigger than the body copy and 2 smaller.


Vertical rhythm

With our different font-sizes we now need to set everything to a semi-baseline grid—or at least create a harmonious vertical rhythm.

We start by applying a consistent margin to all the typography related elements:

h1, h2, h3, h4, h5, h6,
p, ul, ol, dl, dd, figure,
blockquote, details, hr,
fieldset, pre, table {
  margin: 0 0 1.5rem;

The margin-bottom is the same size as our line-height.

Next, we assign a line-height to every font-size in our type-scale that aligns with our base line-height. The idea behind this alignment is create harmony between the text, especially when two columns of text are beside each other—we want the lines of text to align.

Here’s the formula to calculate the appropriate line-height:

line-height: ceil(font-size ÷ base-line-height) × (base-line-height ÷ font-size)

To calculate the h1 it would look like this:

h1, .exa {
  /* line-height: ceil(1.802 ÷ 1.5) × (1.5 ÷ 1.802) */
  font-size: 1.8020rem;
  line-height: 1.6648;


Re-usable spacers

To keep things consistent throughout our design we want to use a series of consistent bottom margins, usually multiples of the line-height.

So, we can create a series of classes to add consistent margins:

/* Normal, line-height size space */
.push {
  margin-bottom: 1.5rem;

/* No space */
.push-none {
  margin-bottom: 0;

/* Double normal space */
.push-double {
  margin-bottom: 3rem;

/* Half normal space */
.push-half {
  margin-bottom: 0.75rem;

We might even want to add a series of classes for consistent paddings for closed in boxes so they can conform to our baseline grid:

  • gutter padding on the left and right.
  • island padding on all four sides.
  • pad-top, pad-bottom for padding on the top and bottom.

Adding branding

Often we want a different typeface and colours for the headings, it’s best to separate that into another series of classes for reuse.

h1, h2, h3, h4, h5, h6,
.brand {
  font-family: Helvetica, sans-serif;
  color: #393;

.brand-family {
  font-family: Helvetica, sans-serif;

.brand-color {
  color: #393;

Now we can apply these classes to any element to assign them the brand colour or typeface or both.

Bigger fonts on bigger screens

With responsive sites it’s usually a good idea to increase the font-size on larger screens. This provides the benefit of having larger fonts on screens like televisions.

With a few media queries at the top of our typography.css file we can increase sizes incrementally for larger screens.

@media only screen and (min-width: 38em) {

  html {
    font-size: 110%;
    line-height: 1.4;


@media only screen and (min-width: 60em) {

  html {
    font-size: 120%;
    line-height: 1.5;


Complete modular type systems

You probably don’t want to create all the type sizes and scales every time you start a website. So using modular type generator is helpful.

Check out Typografier, a tool I created for myself to generate the code for a responsive, modular type system.

Typografier uses a slightly different line-height calculation than above that creates incremental line-heights that look better at bigger font sizes.

Pre-built modular type frameworks

There’s lots of prototyping frameworks online that come setup with a themes, grids, type systems, and components to help you create a quick website.

A few of the most common ones are:

Typography style guide

When starting a new website it’s best to first consider the typography. I generally like to style all the typography related elements to create a mini styleguide.

See some sample HTML for a type style guide.

Sample styleguides

Video list

  1. Modular typography: Creating a type scale
  2. Modular typography: Creating reusable classes
  3. Modular typography: Vertical rhythm
  4. Modular typography: Classes for consistent spacing
  5. Modular typography: Brand fonts and colours
  6. Modular typography: Examples of use
  7. Modular typography: Bigger fonts on bigger screens