← Portfolio

Technical Documentation

Musical Interval Typography

A type scale derived from the intervals of a musical scale

HTML · CSS custom properties · Zero dependencies  ·  License: CC BY-NC 4.0

Live system controls

Body note03 / leading note06 Body leading note06 H1 note10 / leading note11 H2 note07 / leading note08 H3 note02 / leading note04 Subtitle note04 / leading note07 Code note03 / leading note05 Small note02 / leading note04 Paragraph note04 Section note11 Page top note13 Page bottom note14

Origin

I was trying to build the most beautiful text-based website I could imagine. At some point I asked a question I couldn't stop thinking about: what if font sizes weren't arbitrary? What if, instead of choosing numbers that felt right, you established a ratio — the way you'd establish a color palette — and then let every size, margin, line height, and spacing value derive from it? Lock the designer into a system, and any value you choose will harmonize with all the others, the way notes in a key harmonize. The ratio I chose was a musical interval. Getting the math to actually behave took much longer than expected, but when it clicked, every measurement on the page suddenly belonged.


Summary

This is a pure CSS system — no JavaScript, no build step, no dependencies — in which a single ratio (the minor third, expressed as 32/27) governs every measurement on the page: font sizes, margins, padding, line heights, and vertical rhythm.

The underlying design system is essentially one of math and variables, using only HTML and CSS. It takes inputs for a ratio (ideally a musical interval), a minimum font size (set to 16px for accessibility), and a scaling factor which determines how everything grows in accordance with the viewport width. To best accommodate text-only content, the body width is set to 50% — notice how the padding fluidly expands to fill the screen in the margins as the viewport width is adjusted, while keeping all sizing and spacing related and within bounds.

An interesting aspect of this fluid responsiveness is that there are practically no media queries involved. In truth, there are precisely two in use: one changes the text from justified to left-aligned on small screen sizes for improved aesthetics and legibility; the other sets the viewport width at which point the side margins start to shrink, maintaining a correct and balanced look on all device sizes.

The system is not limited to determining font sizes. Musical intervals are employed wherever possible, so that margins, padding, line heights, header and paragraph spacing (vertical rhythm), and anything else to do with size and space are all based on the one fundamental musical interval.


The Code

The ratio

--fontRatio: calc(32 / 27);

Sets the Font Ratio variable — the basis for the entire system. Preferably a musical interval, though any numerical value in any form will do.

Minimum font size

--minFontSize: calc((16 / var(--fontRatio)) * 1px);

Defines the Minimum Font Size variable, to be used in conjunction with Note 00. Starts at 16px for accessibility.

Note 00 — the root

--note00: clamp(var(--minFontSize), var(--fontSizeGrow), 1000000000px);

Defines the Note 00 variable — the starting point for all other Notes — scaling all the way up to infinity (1 billion pixels, to be precise).

The scale

--note01: calc(var(--note00) * var(--fontRatio));
--note02: calc(var(--note01) * var(--fontRatio));
--note03: calc(var(--note02) * var(--fontRatio));
--note04: calc(var(--note03) * var(--fontRatio));

Each subsequent Note is defined by multiplying the immediately previous Note by the Font Ratio. These Notes are used to size everything. More can be added as needed.

The viewport-width track

The Note system's unit is tied to pixels. In order to adjust how the body and page margins grow and shrink according to viewport width, a parallel system with vw units is required.

--minFontSizeVW: calc((16 / var(--fontRatio)) * 1vw);
--note00VW: clamp(var(--minFontSizeVW), 1vw, 1000000000px);
--note01VW: calc(var(--note00VW) * var(--fontRatio));
--bodyMinWidth: calc(100 / var(--fontRatio) * var(--note01) / 2);
--bodyMinWidthVW: calc(100 / var(--fontRatio) * var(--note01VW) / 2);
--fontSizeGrow: 1vw;

The vw-unit track mirrors the px track and is used exclusively for body and margin proportions.

Body sizing

body {
  width: 50vw;
  min-width: var(--bodyMinWidth);
  margin: auto;
}

@media only screen and (max-width: 767px) {
  body {
    min-width: inherit;
    width: calc(var(--bodyMinWidthVW) / 767 * 100);
  }
}

The only media query concerned with sizing and responsiveness. At 767px the body sizes down using vw-based variables.

The complete block

/*
  The following musical interval system and its associated code,
  created by Raymond Reich for bachtogauss.com,
  is licensed under the CC BY-NC 4.0 Deed License.
  https://creativecommons.org/licenses/by-nc/4.0/deed.en
*/

:root {
  --fontRatio: calc(32 / 27);
  --minFontSize: calc((16 / var(--fontRatio)) * 1px);
  --fontSizeGrow: 1vw;
  --note00: clamp(var(--minFontSize), var(--fontSizeGrow), 1000000000px);
  --note01: calc(var(--note00) * var(--fontRatio));
  --note02: calc(var(--note01) * var(--fontRatio));
  --note03: calc(var(--note02) * var(--fontRatio));
  --note04: calc(var(--note03) * var(--fontRatio));
  --note05: calc(var(--note04) * var(--fontRatio));
  --note06: calc(var(--note05) * var(--fontRatio));
  --note07: calc(var(--note06) * var(--fontRatio));
  --note08: calc(var(--note07) * var(--fontRatio));
  --note09: calc(var(--note08) * var(--fontRatio));
  --note10: calc(var(--note09) * var(--fontRatio));
  --note11: calc(var(--note10) * var(--fontRatio));
  --note12: calc(var(--note11) * var(--fontRatio));
  --note13: calc(var(--note12) * var(--fontRatio));
  --note14: calc(var(--note13) * var(--fontRatio));
  --note15: calc(var(--note14) * var(--fontRatio));
  --note16: calc(var(--note15) * var(--fontRatio));
  --minFontSizeVW: calc((16 / var(--fontRatio)) * 1vw);
  --note00VW: clamp(var(--minFontSizeVW), 1vw, 1000000000px);
  --note01VW: calc(var(--note00VW) * var(--fontRatio));
  --bodyMinWidth: calc(100 / var(--fontRatio) * var(--note01) / 2);
  --bodyMinWidthVW: calc(100 / var(--fontRatio) * var(--note01VW) / 2);
}

body {
  width: 50vw;
  min-width: var(--bodyMinWidth);
  margin: auto;
}

@media only screen and (max-width: 767px) {
  body {
    min-width: inherit;
    width: calc(var(--bodyMinWidthVW) / 767 * 100);
  }
}

The complete block. Free to use with credit, under CC BY-NC 4.0.

Example usage

font-size: var(--note03);
line-height: var(--note06);
margin-top: var(--note08);

How the system's implementation looks for a few properties — in this case, body text on this very page.


Sources & Inspiration

A significant amount was learned, and much inspiration taken, from the following works — upon which this system builds: