Music is fundamentally a mathematical exposition. Concepts like frequency, pitch, and harmony are all mathematically determinable. A single musical note, such as one plucked from a guitar string, is in itself a composition. The different frequencies (or harmonics) together belong to a harmonic series. A harmonic series is a sequence of fractions based on the arithmetic series of incrementation by 1.
1,2,3,4,5,6 // arithmetic series
1,½,⅓,¼,⅕,⅙ // harmonic series
The resulting sound is harmonious because of its regularity. The fundamental frequency is divisible by each of the harmonic frequencies, and each harmonic frequency is the mean of the frequencies on either side of it.
We should aim for visual harmony in our visual layouts. Like the sound of a
plucked string, it should be cohesive. Given we're working predominantly with
text, it's sensible to treat line-height
as a basis for extrapolating values
for white space. A font-size of (implicitly) 1rem
, and a line-height
of 1.5
creates a default value of 1.5rem
. A harmoniously larger space might be 3rem
(2 * 1.5) or 4.5rem
(3 * 1.5).
Creating a sequence of adding 1.5 at each step results in large intervals. Instead we can multiply by 1.5. The result is still regular, but the increments are smaller:
1 * 1.5 // 1.5
1.5 * 1.5 // 2.25
1.5 * 1.5 * 1.5 // 3.375
This algorithm is called modular scale, and like music scale is intended for producing a harmony.
Scale generation tools
https://typescale.com/ https://utopia.fyi/type/calculator/
Using css calc()
In css we can describe our modular scale using the calc()
function, which supports simply arithmetic:
:root {
--ratio: 1.5;
--s-5: calc(var(--s-4) / var(--ratio));
--s-4: calc(var(--s-3) / var(--ratio));
--s-3: calc(var(--s-2) / var(--ratio));
--s-2: calc(var(--s-1) / var(--ratio));
--s-1: calc(var(--s0) / var(--ratio));
--s0: 1rem;
--s1: calc(var(--s0) * var(--ratio));
--s2: calc(var(--s1) * var(--ratio));
--s3: calc(var(--s2) * var(--ratio));
--s4: calc(var(--s3) * var(--ratio));
--s5: calc(var(--s4) * var(--ratio));
In newer version of css the pow()
function is being added:
:root {
--ratio: 1.5rem;
}
.my-element {
/* ↓ 1.5 * 1.5 * 1.5 is equal to 1.5³ */
font-size: pow(var(--ratio), 3);
Honestly though, perhaps simply pre-calculating these values is better so that each of your users wont need to do the same thing.