Skip to content

Instantly share code, notes, and snippets.

@mgsisk
Created December 1, 2022 15:43
Show Gist options
  • Save mgsisk/af002bc17e813851316943921f448792 to your computer and use it in GitHub Desktop.
Save mgsisk/af002bc17e813851316943921f448792 to your computer and use it in GitHub Desktop.
A set of CSS custom properties and calculations for consistent use of a modular scale and vertical rhythm.
:root {
/*
Set the root font size to a variable size that scales with the viewport to
ensure readability at any size. This setting results in a 16pt size on a
viewport that is 320pt wide. Larger vw values increase the scaling rate.
*/
--font-size: 0.8em + 1vw;
/*
Set the root line height to a unitless value; at least 1.5 for readability.
*/
--line-height: 1.5;
/*
Set the scale to any single value, ideally greater than 1 and less then the
line height.
*/
--scale: 1.2;
/* ===== DERIVED VALUES =================================================== */
/*
We'll start by specifying our vertical rhythm unit for use in margin,
padding, and other values that need to be consistently spaced. We can then
calc using this value to create larger or smaller gaps that maintain
vertical rhythm.
*/
--vr: calc(1rem * var(--line-height));
--vr--2: calc(var(--vr) / 2);
--vr-02: calc(var(--vr) * 2);
/* Next we'll build out our scale steps to make other calc's easier. */
--scale--3: calc(var(--scale--2) / var(--scale));
--scale--2: calc(var(--scale--1) / var(--scale));
--scale--1: calc(1 / var(--scale));
--scale-00: 1; /* Step 0 is always 1. */
--scale-01: var(--scale); /* Step 1 is always equal to --scale. */
--scale-02: calc(var(--scale) * var(--scale));
--scale-03: calc(var(--scale) * var(--scale-02));
--scale-04: calc(var(--scale) * var(--scale-03));
--scale-05: calc(var(--scale) * var(--scale-04));
/* Now we can set our font sizes using rem and the scale values. */
--font-size--1: calc(1rem * var(--scale--1));
--font-size-00: 1rem; /* Step 0 is always equal to the root font size. */
--font-size-01: calc(1rem * var(--scale));
--font-size-02: calc(1rem * var(--scale-02));
--font-size-03: calc(1rem * var(--scale-03));
--font-size-04: calc(1rem * var(--scale-04));
--font-size-05: calc(1rem * var(--scale-05));
/*
We can also set unitless line heights that maintain vertical rhtyhm. This is
a little trickier; we start by dividing our base line height by the scale
value. For smaller sizes, this will give an appropriate line height. For
larger sizes, we'll need to then multiply this value by an appropriate
amount to get a line height that comfortably fits the matching font size and
maintains vertical rhythm.
For now, we have to just pick an integer that looks good (or even just set
these as a multiple of our vertical rhythm unit). When the round() function
is eventually implemented, we can replace this with a complete formula to
automatically calc an appropriate unitless line height:
line-height / scale-n * ceil(minimum / (line-height / scale-n))
The minimum value in the formula above should be at least 1; setting it to
the base scale value is usually a good idea. A lower minimum results in
tighter line heights, with values less than 1 potentially causing overlap.
*/
--line-height--1: calc(var(--line-height) / var(--scale--1));
--line-height-00: var(--line-height); /* Step 0 is always equal to --line-height. */
--line-height-01: calc(var(--line-height) / var(--scale) * 1);
/* 1 could also work for --line-height-02, but it would be really tight. */
--line-height-02: calc(var(--line-height) / var(--scale-02) * 2);
--line-height-03: calc(var(--line-height) / var(--scale-03) * 2);
--line-height-04: calc(var(--line-height) / var(--scale-04) * 2);
--line-height-05: calc(var(--line-height) / var(--scale-05) * 2);
}
/*
Set the root font size and line height. We'll use the scaled values for all
other elements.
*/
html {
font-size: var(--font-size);
line-height: var(--line-height);
}
h1 {
font-size: var(--font-size-05);
line-height: var(--line-height-05);
margin: 0 0 calc(var(--vr) * 3);
}
h2 {
font-size: var(--font-size-04);
line-height: var(--line-height-04);
margin: 0 0 var(--vr-02);
}
h3 {
font-size: var(--font-size-03);
line-height: var(--line-height-03);
margin: 0 0 var(--vr);
}
h4 {
font-size: var(--font-size-02);
line-height: var(--line-height-02);
margin: 0 0 var(--vr);
}
/*
We have to double our use of --vr--2 here, as it's only half of our total
vertical rhythm unit.
*/
h5 {
font-size: var(--font-size-01);
line-height: var(--line-height-01);
margin: var(--vr--2) 0;
}
/*
Using --font-size-00 (or 1rem) here is deliberate; because of how --font-size
is set, using it on any element other than the root element could result in
unexpected results.
*/
h6 {
font-size: var(--font-size-00);
line-height: var(--line-height-00);
}
small {
font-size: var(--font-size--1);
line-height: var(--line-height--1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment