Github link

What is GutenType?

What is GutenType?

What is GutenType?

What is GutenType?

What is GutenType?
Jan 31, 2021 – Awjin Ahn

GutenType is a Sass library that creates correct typography.

Wait. Can typography be correct?

Yes. Typography was solved centuries ago, through science, by print publishers. They created rules for proportionally scaling the size of headings, calculating whitespace, positioning lines, etc. that, when systematically applied, yield text that is a joy to read. This explains why books feel nicer to read in print than on the web. Of course, the screen beaming light into your eyes is another big reason, but there are tons of improvements we can bring to web typography to close the UX gap.

We need to translate the rules of print into code. As it turns out, this task is tedious and weird. For example, because text has a line-height, the same value of whitespace applied to the margin of a p is larger than when it's applied to the margin of an img. There are countless minutiae like this to comb through and fix.

And, anecdotally—I've wasted countless hours throughout my career fiddling with the margins of an h3 until it "felt" just "right". I'm tired of making these imprecise, manual tweaks constantly.

So... what's the solution?

GutenType. Hear me out.

It handles all of that minutiae for you. Calling its press() mixin assigns a base font-size to the html element, so that all other styles can be derived from 1rem. Then, it generates the typography system.

@use 'guten-type';

main {

It ships with a bunch of default base values. This website is styled with those defaults. To customize them, call the set() mixin before pressing. Since GutenType has typographic rules baked in, it will always generate correct styles from the given config.

@use 'guten-type';

main {
  /* STEP 1 (optional): Configure the module. */
  @include guten-type.set(
    $line-height: 1.4,
    $font-size: 18px,
    $font-stack: (
      'heading': ('PT Serif', serif),
      'body': ('PT Sans', sans-serif),
      'mono': ('Roboto Mono', monospace),

  /* STEP 2: Use the module. */

This is especially powerful if you have a static website or blog that builds HTML from Markdown, since press() styles every element that Markdown can generate. Configure it once, then enjoy your super readable website. As an example, this website is styled throughout with GutenType, and has a blog section made with Jekyll.

Going Deeper

One key concept is typographic scale. To create rhythm and harmony, text size should scale at a fixed ratio as you move up the hierarchy. If p is sized at 1rem, the smallest heading should have a font-size of 1rem * ratio, the next heading up should be 1rem * ratio2, and so on. The same applies to whitespace. GutenType does these calculations for you.

Sad boi
Writing without GutenType: sad

There's also the concept of a responsive-breakpoint. If set, the font-size will seamlessly transition from static to responsive at the breakpoint. For example, let's say that font-size is 16px and the responsive-breakpoint is 1200px. GutenType calculates how much vw is equal to 16px at a viewport size of 1200px. When the breakpoint triggers, it sets font-size to that vw value. As the viewport increases beyond the breakpoint, font-size scales with it, "locking in" the relative size and proportions of text. It's hard to describe in words, so I'd encourage you to resize this window and see how it behaves.

Other Tidbits

If you want to use the config values in your Sass code, you can access them via getters like guten-type.whitespace().

This is the default font-stack.
Heading sans-serif
Body Georgia, serif
Mono Andale Mono, Lucida Console, monospace

There's more, but I think it's time to wrap up this post.

Closing Remarks

  1. Thank you for listening to my opinions.
  2. Whitespace is hard but always worth it.
  3. If your website is text-heavy, GutenType could strongly improve its UX in just two lines of code.
    • As an added bonus, you'll never have to write typographic styles again.

Here's the Github source and the npm package. I hope you find it helpful. Please file an issue or a PR for improvements.